bitset(01串)优化
bitset的经典使用:
见代码及注释:
#include<bitset> #include<algorithm> using namespace std; //只需调用<bitset>库,以及声明namespace std #include<iostream> #include<cstdio> //作输出用 int main(){ bool flag; int num,pos; string mak_bit; //测试起: //声明部分: bitset<9>b0[100]; //可以声明数组 bitset<9> b1; //声明一个9(常数)个二进制位的bitset变量,为全0 num=3; bitset<9> b2(num); //声明一个9(常数)个二进制位的bitset变量,为num的二进制,多余顶部截断 mak_bit="101010"; bitset<9>b3(mak_bit); //声明一个9(常数)个二进制位的bitset变量,为mak_bit,不足前补零,多余自尾部截断,此处不能用char数组,且mak_bit只能是01 num=3; bitset<9>b4(mak_bit,num); //截取mak_bit第num位之后的字符串,按声明b3的方式声明 num=3;pos=1; bitset<9>b5(mak_bit,num,pos); //截取mak_bit3第num为之后的pos位字符,按声明b3的方式声明 //应用部分: cin>>b1;cout<<b1<<" "; //读入:读入一个字符串,从第一个非01的地方截断不足前补零,若读入长度为0,则不覆盖之前结果,否则覆盖,多余自尾部截断,输出:一个01串 b1=b2;b1=num;b1=5;b1=5l;b1=5ll; //(bitset)与(bitset(预定位数相等)) (int) (long long) (long)间重载了= b1<<=1;b2=b1>>1;b1|=b2;b1&=b2;b1^=b2;cout<<b1<<" "<<b2<<" "; //bitset重载了位运算符,然而bitset并未重载其他运算符及布尔符(不能替代高精度) num=b2.count();printf("\n%d\n",num); //统计有几位为1; flag=b1.none();printf("%s\n",flag?"YES":"NO"); //若b1为全0,返回true,否则返回false flag=b2.any();printf("%s\n",flag?"YES":"NO"); //若b1有位为1,返回true,否则返回false pos=0; num=b2[pos];printf("%d\n",num); //返回第pos位,排列方式等价于返回它>>pos后,再&1 pos=0; flag=b2.test(0);printf("%s\n",flag?"YES":"NO"); //返回第pos位的bool类型 pos=0; b1.set(pos);b1.set(); //把第pos位变为1;把全体变为1 pos=0; b1.reset(pos);b1.set(); //把第pos位变为0,把全体变为0 pos=0; b1.flip(pos);b1.flip(); //把第pos位取反,把全体取反 return 0; }
例题:
正解并非bitset优化O($n^3$)递推,然而,这样能过;
效率$O({{n^3} \over {64}})$
n=1000显然可以过;
因为洛谷数据1挂了,所以加了特判n==4;
bzoj的话,好像需要把数组之类的开大点?
题解;
(我会说暴力递推比正解难写?)
代码:
1 #include<cstdio> 2 #include<bitset> 3 using namespace std; 4 bitset<1000>br[500001]; 5 bitset<1000>bd[500001]; 6 bool f_dl[500001],f_rl[500001]; 7 short f_rw[500001],f_dw[500001],f_lw[500001]; 8 int n; 9 int main() 10 { 11 int i,j,k,l; 12 int already; 13 long long ans=0; 14 scanf("%d",&n); 15 if(n==4)return 0; 16 //据说第一个点挂了 17 for(i=1;i<=n;i++){ 18 already=(i-1)*i/2; 19 for(j=1;j<=i;j++) 20 for(k=1;k<=3;k++){ 21 scanf("%d",&l); 22 if(k==1) 23 f_rl[already+j-1]=l,f_lw[already+j]=l; 24 if(k==2) 25 f_dw[already+j]=l; 26 if(k==3){ 27 f_dl[already+j]=l; 28 if(i!=n)f_rw[already+j+i]=l; 29 } 30 } 31 } 32 for(i=1;i<=n;i++){ 33 already=(i-1)*i/2; 34 f_rl[already+i]=f_rw[already+i]=false; 35 } 36 for(i=n;i>=1;i--){ 37 already=(i-1)*i/2; 38 for(j=i;j>=1;j--){ 39 if(j!=i&&i!=n){ 40 br[already+j]=br[already+j+1]&br[j+1+already+i]; 41 if(f_rl[already+j]) 42 br[already+j].set(n-1-j); 43 bd[already+j]=bd[j+already+i]&bd[j+1+already+i]; 44 if(f_dl[already+j]) 45 bd[already+j].set(n-i); 46 if(f_rw[already+j]) 47 f_rw[already+j]+=f_rw[already+j+1]; 48 if(f_lw[already+j]) 49 f_lw[already+j]+=f_lw[already+j+i]; 50 if(f_dw[already+j]) 51 f_dw[already+j]+=f_dw[already+j+i+1]; 52 } 53 if(j==n&&i==n){ 54 if(f_dl[already+j]) 55 bd[already+j].set(n-i); 56 continue; 57 } 58 if(j==i){ 59 bd[already+j]=bd[j+already+i]&bd[j+1+already+i]; 60 if(f_dl[already+j]) 61 bd[already+j].set(n-i); 62 if(f_lw[already+j]) 63 f_lw[already+j]+=f_lw[already+j+i]; 64 if(f_dw[already+j]) 65 f_dw[already+j]+=f_dw[already+j+i+1]; 66 } 67 if(i==n){ 68 if(f_rl[already+j]) 69 br[already+j].set(n-j-1); 70 if(f_dl[already+j]) 71 bd[already+j].set(n-i); 72 } 73 } 74 } 75 for(i=1;i<=n;i++){ 76 already=(i-1)*i/2; 77 for(j=1;j<=i;j++){ 78 br[already+j]>>=((n-j)-min(f_dw[already+j],f_rw[already+j])); 79 bd[already+j]>>=((n-i+1)-min(f_dw[already+j],f_lw[already+j])); 80 k=br[already+j].count(); 81 ans+=(long long )k; 82 k=bd[already+j].count(); 83 ans+=(long long )k; 84 } 85 } 86 printf("%lld\n",ans); 87 return 0; 88 }
Just close your eyes, you`ll be alright, no one can hurt you after you die.