bitset(01串)优化

2023-05-03,

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<>b0[];
//可以声明数组 bitset<> b1;
//声明一个9(常数)个二进制位的bitset变量,为全0 num=;
bitset<> b2(num);
//声明一个9(常数)个二进制位的bitset变量,为num的二进制,多余顶部截断 mak_bit="";
bitset<>b3(mak_bit);
//声明一个9(常数)个二进制位的bitset变量,为mak_bit,不足前补零,多余自尾部截断,此处不能用char数组,且mak_bit只能是01 num=;
bitset<>b4(mak_bit,num);
//截取mak_bit第num位之后的字符串,按声明b3的方式声明 num=;pos=;
bitset<>b5(mak_bit,num,pos);
//截取mak_bit3第num为之后的pos位字符,按声明b3的方式声明 //应用部分: cin>>b1;cout<<b1<<" ";
//读入:读入一个字符串,从第一个非01的地方截断不足前补零,若读入长度为0,则不覆盖之前结果,否则覆盖,多余自尾部截断,输出:一个01串 b1=b2;b1=num;b1=;b1=5l;b1=5ll;
//(bitset)与(bitset(预定位数相等)) (int) (long long) (long)间重载了= b1<<=;b2=b1>>;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=;
num=b2[pos];printf("%d\n",num);
//返回第pos位,排列方式等价于返回它>>pos后,再&1 pos=;
flag=b2.test();printf("%s\n",flag?"YES":"NO");
//返回第pos位的bool类型 pos=;
b1.set(pos);b1.set();
//把第pos位变为1;把全体变为1 pos=;
b1.reset(pos);b1.set();
//把第pos位变为0,把全体变为0 pos=;
b1.flip(pos);b1.flip();
//把第pos位取反,把全体取反 return ;
}

例题:

[HNOI2005]数三角形

正解并非bitset优化O($n^3$)递推,然而,这样能过;

效率$O({{n^3} \over {64}})$

n=1000显然可以过;

因为洛谷数据1挂了,所以加了特判n==4;

bzoj的话,好像需要把数组之类的开大点?

题解;

(我会说暴力递推比正解难写?)

代码:

 #include<cstdio>
#include<bitset>
using namespace std;
bitset<>br[];
bitset<>bd[];
bool f_dl[],f_rl[];
short f_rw[],f_dw[],f_lw[];
int n;
int main()
{
int i,j,k,l;
int already;
long long ans=;
scanf("%d",&n);
if(n==)return ;
//据说第一个点挂了
for(i=;i<=n;i++){
already=(i-)*i/;
for(j=;j<=i;j++)
for(k=;k<=;k++){
scanf("%d",&l);
if(k==)
f_rl[already+j-]=l,f_lw[already+j]=l;
if(k==)
f_dw[already+j]=l;
if(k==){
f_dl[already+j]=l;
if(i!=n)f_rw[already+j+i]=l;
}
}
}
for(i=;i<=n;i++){
already=(i-)*i/;
f_rl[already+i]=f_rw[already+i]=false;
}
for(i=n;i>=;i--){
already=(i-)*i/;
for(j=i;j>=;j--){
if(j!=i&&i!=n){
br[already+j]=br[already+j+]&br[j++already+i];
if(f_rl[already+j])
br[already+j].set(n--j);
bd[already+j]=bd[j+already+i]&bd[j++already+i];
if(f_dl[already+j])
bd[already+j].set(n-i);
if(f_rw[already+j])
f_rw[already+j]+=f_rw[already+j+];
if(f_lw[already+j])
f_lw[already+j]+=f_lw[already+j+i];
if(f_dw[already+j])
f_dw[already+j]+=f_dw[already+j+i+];
}
if(j==n&&i==n){
if(f_dl[already+j])
bd[already+j].set(n-i);
continue;
}
if(j==i){
bd[already+j]=bd[j+already+i]&bd[j++already+i];
if(f_dl[already+j])
bd[already+j].set(n-i);
if(f_lw[already+j])
f_lw[already+j]+=f_lw[already+j+i];
if(f_dw[already+j])
f_dw[already+j]+=f_dw[already+j+i+];
}
if(i==n){
if(f_rl[already+j])
br[already+j].set(n-j-);
if(f_dl[already+j])
bd[already+j].set(n-i);
}
}
}
for(i=;i<=n;i++){
already=(i-)*i/;
for(j=;j<=i;j++){
br[already+j]>>=((n-j)-min(f_dw[already+j],f_rw[already+j]));
bd[already+j]>>=((n-i+)-min(f_dw[already+j],f_lw[already+j]));
k=br[already+j].count();
ans+=(long long )k;
k=bd[already+j].count();
ans+=(long long )k;
}
}
printf("%lld\n",ans);
return ;
}

SB暴力

bitset(01串)优化的相关教程结束。

《bitset(01串)优化.doc》

下载本文的Word格式文档,以方便收藏与打印。