bjoi 2008 序列 数据结构

思路: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 }
原文地址:https://www.cnblogs.com/myoi/p/2485096.html