【Bitset】 BZOJ4810
难得学习一下C++的库。。【至今连map,vector都没用过的我。。
首先#include<bitset>或<bits/stdc++.h>
定义函数: {
bitset <15> b; 15是bitset长度 之后我就写成n了,b是变量名
或: string s='01001'; bitset <n> b(s); 若s不是01串会报错。若strlen(s)>n, bitset会只取s的前n位 否则 bitset会在前面补0 【注:举例n=10, cout<<b 后得到的将是0000001001】
或: bitset <n> b(5); 这里的5 是个unsigned long long, bitset会将其转化成二进制, 若n小于其二进制位数,, 会保留低位的n个。
}
当然 也可以转回来{
转unsigned: unsigned int x=b.to_ulong(); printf("%u",x); 就是把bitset转成十进制,to_ulong()是个unsigned int; b的位数大于32没有关系 但是b转成十进制的值大于等于1LL<<32(即爆unsigned)时 会报错。注意 这里若cout<<b是 0000001001 则x=9 ,所以右边是低位
转string: S=b.to_string(); S的strlen将和b的位数相同。
}
{
还是上面那个例子 cout<<b是 0000001001 则,最右边的1是 bitset的第0位 也就是低位,
b.flip(2) 就是把第2位取反 cout: 0000001101
b.set(2) 就是把第2位 置为1 cout: 0000001101
b.reset(0) 就是把第0位 置为0 cout: 0000001000
如果 位置超过范围就会报错
}
b[pos] 访问b中在pos处二进制位
而且位数相同的bitset之间可以用位运算 写法同整数位运算
只要记住 bitset 在cout的时候 右边的是下标小的,下标i就表示二进制中2^i,其余就和整数理解一样了。
后面的拖别人的博客了:
常用的成员函数:
b.any() b中是否存在置为1的二进制位?
b.none() b中不存在置为1的二进制位吗?
b.count() b中置为1的二进制位的个数
b.size() b中二进制位数的个数
b.test(pos) b中在pos处的二进制位置为1么?
b.set() 把b中所有二进制位都置为1
b.set(pos) 把b中在pos处的二进制位置为1
b.reset( ) 把b中所有二进制位都置为0
b.reset( pos ) 把b中在pos处的二进制位置置为0
b.flip( ) 把b中所有二进制位逐位取反
b.flip( pos ) 把b中在pos处的二进制位取反
b.to_ulong( ) 把b中同样的二进制位返回一个unsigned
os << b 把b中的位集输出到os流
还有一个: 如 bitset <3> a; 若a={110} 则a<<1 ={100} 即全体左移 多出来的那些补零。
那么现在就可以做这道题了。
就是莫队 然后 两个bitset互相&一下 就可以直接求答案了。。学bitset只是为了比手动压位方便一些、
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int O=315; 4 const int X=100000; 5 int f[100005],a[100005],n,m,x; 6 struct opt{ int o,l,r,x,i; }op[100005]; 7 bitset <X+1> b,c,d,e; 8 bool cmp(opt a,opt b){ if (a.l/O!=b.l/O) return a.l<b.l; else return a.r<b.r; } 9 bool cmi(opt a,opt b){ return a.i<b.i; } 10 int main(){ 11 scanf("%d%d",&n,&m); 12 for (int i=1;i<=n;++i) scanf("%d",&a[i]); 13 for (int i=1;i<=m;++i) scanf("%d%d%d%d",&op[i].o,&op[i].l,&op[i].r,&op[i].x),op[i].i=i; 14 sort(op+1,op+m+1,cmp); op[0].l=-O; 15 for (int i=1;i<=m;++i){ 16 if (op[i].l/O==op[i-1].l/O){ 17 for (int j=op[i-1].l;j<op[i].l;++j) {--f[a[j]]; if (!f[a[j]]) b.reset(a[j]),c.reset(X-a[j]);} 18 for (int j=op[i-1].l-1;j>=op[i].l;--j) {if (!f[a[j]]) b.set(a[j]),c.set(X-a[j]); ++f[a[j]];} 19 for (int j=op[i-1].r+1;j<=op[i].r;++j) {if (!f[a[j]]) b.set(a[j]),c.set(X-a[j]); ++f[a[j]];} 20 }else{ 21 for (int j=op[i-1].l;j<=op[i-1].r;++j) {f[a[j]]=0; b.reset(a[j]); c.reset(X-a[j]);} 22 for (int j=op[i].l;j<=op[i].r;++j) {if (!f[a[j]]) b.set(a[j]),c.set(X-a[j]); ++f[a[j]];} 23 } 24 x=op[i].x; 25 if (op[i].o==1){ 26 d=b>>x; d&=b; 27 op[i].x=d.any(); 28 }else 29 if (op[i].o==2){ 30 e=c<<(x+1>>1)>>(X-x+(x+1>>1)); 31 d=b<<(X-x/2)>>(X-x/2); d&=e; //<<X-r>>X-r+l 32 op[i].x=d.any(); 33 }else{ 34 x=0; 35 for (int j=1,s=floor(sqrt(op[i].x));j<=s;++j) 36 if (!(op[i].x%j)&&f[j]&&f[op[i].x/j]) {x=1; break;} 37 op[i].x=x; 38 } 39 } 40 sort(op+1,op+m+1,cmi); 41 for (int i=1;i<=m;++i) op[i].x?puts("yuno"):puts("yumi"); 42 return 0; 43 }