首页 > 代码库 > [BZOJ2568]比特集合
[BZOJ2568]比特集合
这道题的思路还是比较好想的喵~
首先令数组 C[k][num] 表示 2 进制最后 k 位 <=num 的数的个数
查询第 k 位为 1 即询问 C[k][(1<<k+1)-1]-C[k][(1<<k)-1] 的值
因为要支持插入、删除,C 数组应使用树状数组或线段树来维护
然后可以用类似于标记永久化的方法,把 ADD 操作搞掉喵~
但是细节部分处理起来就比较麻烦了,WA 了好多次莫名其妙的 A 了
我也不敢写太多……
1 #include <cstdio> 2 #include <map> 3 4 namespace IOspace 5 { 6 inline char getch() 7 { 8 register char ch; 9 do ch=getchar(); while (ch!=‘A‘ && ch!=‘I‘ && ch!=‘D‘ && ch!=‘Q‘);10 return ch;11 }12 inline int getint()13 {14 register int num=0;15 register char ch;16 do ch=getchar(); while (ch<‘0‘ || ch>‘9‘);17 do num=num*10+ch-‘0‘, ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘);18 return num;19 }20 inline void putint(int num, char ch=‘\n‘)21 {22 char stack[15];23 register int top=0;24 if (num==0) stack[top=1]=‘0‘;25 for ( ;num;num/=10) stack[++top]=num%10+‘0‘;26 for ( ;top;top--) putchar(stack[top]);27 if (ch) putchar(ch);28 }29 }30 31 int N;32 int add;33 std::map<int, int> s;34 int sum[17][65537];35 inline int lim(int x) {return (1<<x+1)-1;}36 inline int min(int x, int y) {return x<y?x:y;}37 inline int max(int x, int y) {return x>y?x:y;}38 inline int lowbit(int x) {return x & -x;}39 inline void update(int, int, int);40 inline int query(int, int);41 42 int main()43 {44 N=IOspace::getint();45 for ( ;N;N--)46 {47 char ch=IOspace::getch(); int x=IOspace::getint();48 if (ch==‘A‘) add+=x;49 if (ch==‘I‘)50 {51 x-=add;52 s[x]++;53 for (int i=0;i<16;i++) update(i, (x & lim(i))+1, 1);54 }55 if (ch==‘D‘)56 {57 x-=add;58 int t=s[x];59 s[x]=0;60 for (int i=0;i<16;i++) update(i, (x & lim(i))+1, -t);61 }62 if (ch==‘Q‘)63 {64 int l=1<<x, r=lim(x);65 int ans=0;66 ans+=query(x, min(max(r-(add & lim(x))+1, 0), 1<<16));67 ans-=query(x, min(max(l-(add & lim(x)), 0), 1<<16));68 l+=1<<x+1, r+=1<<x+1;69 ans+=query(x, min(max(r-(add & lim(x))+1, 0), 1<<16));70 ans-=query(x, min(max(l-(add & lim(x)), 0), 1<<16));71 IOspace::putint(ans);72 }73 }74 75 return 0;76 }77 inline void update(int k, int i, int v)78 {79 for ( ;i<=1<<16;i+=lowbit(i)) sum[k][i]+=v;80 }81 inline int query(int k, int i)82 {83 int ret=0;84 for ( ;i;i-=lowbit(i)) ret+=sum[k][i];85 return ret;86 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。