位元集合是一種抽象資料型別(abstract data type) ,其包含乙個集合s,並支援如下幾種操作:
ins m : 將元素 m 插入到集合s中;
del m : 將集合s中所有等於 m 的元素刪除;
add m : 將集合s中的所有元素都增加數值m ;
qbit k : 查詢集合中有多少個元素滿足其二進位制的第 k位為 1 。
初始時,集合s為空集。請實現乙個位元集合,並對於所有的qbit操作輸出相應的答案。
輸入第一行包含乙個正整數n,表示操作的數目。
接下來n行,每行為乙個操作,格式見問題描述。
對於每乙個qbit操作,輸出一行,表示相應的答案。
8ins 1
qbit 0
add 1
qbit 0
qbit 1
del 2
ins 1
qbit 110
10資料規模和約定
時間限制2s。
對於30%的資料,1 ≤ n ≤ 10000。
對於100%的資料,1 ≤ n ≤ 500000;qbit操作中的k滿足, 0 ≤ k < 16。ins/del操作中,滿足0 ≤ m ≤ 10^9;add操作中, 滿足0 ≤ m ≤ 1000。
注意集合s可以包含多個重複元素。
正解:樹狀陣列。
維護$16$個樹狀陣列,其中第$i$個表示每個數$ \mod 2^$的數是什麼。
插入刪除直接在樹狀陣列裡面搞就行了,查詢某個數的個數直接$hash$就行了。
區間加就直接對於每個樹狀陣列記錄目前的$0$在哪個位置,不對樹狀陣列進行修改。
查詢就直接在$2^$的樹狀陣列上查詢$[2^,2^-1]$的數有多少個就行了。
1 #include 2#define il inline
3#define rg register
4#define ll long long
5#define lb(x) (x & -x)
6#define rhl (1253557)78
using
namespace
std;910
struct edgeg[1000010
];11
12int c[17][150010],bin[17],head[rhl+10
],n,m,num;
13char ch[5
];14
15 il int
gi()
2223 il void insert(rg int
from,rg int to,rg int
v),head[from]=num; return;25
}2627 il void add(rg int id,rg int x,rg int
v)30
31 il int query(rg int id,rg int
x)34
35 il void hshadd(rg int x,rg int
v)39 insert(wyh,x,v); return;40
}4142 il int hshquery(rg int
x)48
49int
main()
63 hshadd(x-m,1
);64}65
if (ch[0]=='d'
)70 hshadd(x-m,-k);71}
72if (ch[0]=='
a') m+=gi();
73if (ch[0]=='q'
)79}80
return0;
81 }
BZOJ 2568 位元集合
題意 維護乙個集合s,支援以下操作 1 ins m 將元素 m 插入到集合s中 2 del m 將集合s中所有等於 m 的元素刪除 3 add m 將集合s中的所有元素都增加數值m 4 qbit k 查詢集合中有多少個元素滿足其二進位制的第 k位為 1 思路 1 add 操作的那個和單獨拿出來,設為...
BZOJ 2301 莫比烏斯
比較裸的一道莫比烏斯入門題 具體題解網上多的是 比較簡單 不知道為什麼別人 都那麼長 沒有我的優雅哈哈哈 這題不要列舉 要分塊處理 ac includeusing namespace std typedef long long ll const ll n 1e6 ll miu n 10 v n 10...
bzoj 2440 (莫比烏斯函式)
bzoj 2440 完全平方數 題意 找出第k個不是完全平方數的正整數倍的數。例如 4 9 16 25 36什麼的 通過容斥原理,我們減去所有完全數 4有n 4個,但是先36這種會被重複減去,所有我們還需要加上類似36的數,然後你會發現這些數前面的符號和他們開根號的 莫比烏斯函式一樣 資料很大有1e...