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;
} 

例题:

[HNOI2005]数三角形

正解并非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 }
SB暴力

 

posted @ 2017-10-11 21:59  F.W.Nietzsche  阅读(477)  评论(0编辑  收藏  举报