bzoj2568 比特集合

Description

  比特集合是一种抽象数据类型(Abstract Data Type) ,其包含一个集合S,并支持如下几种操作:
  INS M : 将元素 M 插入到集合S中;
  DEL M : 将集合S中所有等于 M 的元素删除;
  ADD M : 将集合S中的所有元素都增加数值M ;
  QBIT k : 查询集合中有多少个元素满足其二进制的第 k位为 1 。
  初始时,集合S为空集。请实现一个比特集合,并对于所有的QBIT操作输出相应的答案。

Input

  输入第一行包含一个正整数N,表示操作的数目。
  接下来N行,每行为一个操作,格式见问题描述。

Output

  对于每一个QBIT操作,输出一行,表示相应的答案。

Sample Input

8
INS 1
QBIT 0
ADD 1
QBIT 0
QBIT 1
DEL 2
INS 1
QBIT 1

Sample Output

1
0
1
0

HINT 

数据规模和约定
时间限制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^{i+1}$的数是什么。

插入删除直接在树状数组里面搞就行了,查询某个数的个数直接$hash$就行了。

区间加就直接对于每个树状数组记录目前的$0$在哪个位置,不对树状数组进行修改。

查询就直接在$2^{k+1}$的树状数组上查询$[2^{k},2^{k+1}-1]$的数有多少个就行了。

 

 1 #include <bits/stdc++.h>
 2 #define il inline
 3 #define RG register
 4 #define ll long long
 5 #define lb(x) (x & -x)
 6 #define rhl (1253557)
 7  
 8 using namespace std;
 9  
10 struct edge{ int nt,to,v; }g[1000010];
11  
12 int c[17][150010],bin[17],head[rhl+10],n,m,num;
13 char ch[5];
14  
15 il int gi(){
16   RG int x=0,q=1; RG char ch=getchar();
17   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
18   if (ch=='-') q=-1,ch=getchar();
19   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
20   return q*x;
21 }
22  
23 il void insert(RG int from,RG int to,RG int v){
24   g[++num]=(edge){head[from],to,v},head[from]=num; return;
25 }
26  
27 il void add(RG int id,RG int x,RG int v){
28   for (;x<=bin[id+1];x+=lb(x)) c[id][x]+=v; return;
29 }
30  
31 il int query(RG int id,RG int x){
32   RG int res=0; for (;x;x-=lb(x)) res+=c[id][x]; return res;
33 }
34  
35 il void hshadd(RG int x,RG int v){
36   RG int wyh=(x%rhl+rhl)%rhl;
37   for (RG int i=head[wyh];i;i=g[i].nt)
38     if (g[i].to==x){ g[i].v+=v; return; }
39   insert(wyh,x,v); return;
40 }
41  
42 il int hshquery(RG int x){
43   RG int wyh=(x%rhl+rhl)%rhl;
44   for (RG int i=head[wyh];i;i=g[i].nt)
45     if (g[i].to==x) return g[i].v;
46   return 0;
47 }
48  
49 int main(){
50 #ifndef ONLINE_JUDGE
51   freopen("bit.in","r",stdin);
52   freopen("bit.out","w",stdout);
53 #endif
54   n=gi(),bin[0]=1;
55   for (RG int i=1;i<=16;++i) bin[i]=bin[i-1]<<1;
56   for (RG int i=1,x,k,l,r;i<=n;++i){
57     scanf("%s",ch);
58     if (ch[0]=='I'){
59       x=gi();
60       for (RG int j=0,y;j<=15;++j){
61     y=(x-m)%bin[j+1]; if (y<=0) y+=bin[j+1]; add(j,y,1);
62       }
63       hshadd(x-m,1);
64     }
65     if (ch[0]=='D'){
66       x=gi(),k=hshquery(x-m); if (!k) continue;
67       for (RG int j=0,y;j<=15;++j){
68     y=(x-m)%bin[j+1]; if (y<=0) y+=bin[j+1]; add(j,y,-k);
69       }
70       hshadd(x-m,-k);
71     }
72     if (ch[0]=='A') m+=gi();
73     if (ch[0]=='Q'){
74       k=gi(),l=(bin[k]-m)%bin[k+1],r=(bin[k+1]-1-m)%bin[k+1];
75       if (l<=0) l+=bin[k+1]; if (r<=0) r+=bin[k+1];
76       if (l<=r) printf("%d\n",query(k,r)-query(k,l-1));
77       else printf("%d\n",query(k,r)-query(k,l-1)+query(k,bin[k+1]));
78     }
79   }
80   return 0;
81 }

 

posted @ 2017-09-03 17:39  wfj_2048  阅读(349)  评论(0编辑  收藏  举报