思路:ak第i位是1 本质就是 akmod(2^(i+1))属于[2^i,2^(i+1)-1]
开16个线段树
P.S. 答案可能会爆int
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 using namespace std; 6 struct node 7 { 8 int left,right,num; 9 }; 10 node tree[17][1<<18]; 11 int a[17][1<<16]; 12 int n,m; 13 char c[10]; 14 int build_tree(int t,int i) 15 { 16 if(tree[t][i].left==tree[t][i].right) 17 return tree[t][i].num=a[t][tree[t][i].right]; 18 int mid=(tree[t][i].left+tree[t][i].right)/2; 19 tree[t][2*i].left=tree[t][i].left; tree[t][2*i].right=mid; 20 tree[t][2*i+1].left=mid+1; tree[t][2*i+1].right=tree[t][i].right; 21 return tree[t][i].num=build_tree(t,2*i)+build_tree(t,2*i+1); 22 } 23 int search(int t,int i,int x,int y) 24 { 25 if(tree[t][i].left==x&&tree[t][i].right==y) 26 return tree[t][i].num; 27 int mid=(tree[t][i].left+tree[t][i].right)/2; 28 if(y<=mid) 29 return search(t,2*i,x,y); 30 else if(x>mid) 31 return search(t,2*i+1,x,y); 32 else 33 return search(t,2*i,x,mid)+search(t,2*i+1,mid+1,y); 34 } 35 int main() 36 { 37 memset(a,0,sizeof(a)); 38 scanf("%d%d",&n,&m); 39 int i,j,x,y,p,q; 40 long long ans=0; 41 for(i=1;i<=n;i++) 42 { 43 scanf("%d",&x); 44 for(j=1;j<=16;j++) 45 a[j][x%(1<<j)]++; 46 } 47 for(i=1;i<=16;i++) 48 { 49 tree[i][1].left=0; tree[i][1].right=(1<<i)-1; 50 build_tree(i,1); 51 } 52 x=0; 53 for(i=1;i<=m;i++) 54 { 55 scanf("%s",c); 56 if(c[0]=='A') 57 { 58 scanf("%d",&y); 59 x+=y; 60 } 61 if(c[0]=='Q') 62 { 63 scanf("%d",&y); 64 if(y>=16) continue; 65 p=(((1<<y)-x)%(1<<(y+1))+(1<<(y+1)))%(1<<(y+1)); 66 q=((((1<<(y+1))-1)-x)%(1<<(y+1))+(1<<(y+1)))%(1<<(y+1)); 67 if(p>q) 68 ans+=search(y+1,1,p,(1<<(y+1))-1)+search(y+1,1,0,q); 69 else 70 ans+=search(y+1,1,p,q); 71 } 72 } 73 printf("%lld\n",ans); 74 return 0; 75 }