bitset

1.位运算的常见函数
__builtin_popcount(x) //x二进制内1的个数(unsigned int)
__builtin_popcountll(x) //longlong版本
__builtin_parity(x) //二进制下的1的个数的奇偶性
__builtin_parityll(x) //long long版本
__builtin_ctz(x)//x二进制末尾0的个数
__builtin_clz(x)//x二进制开头0的个数
log2(x)=31-__builtin_clz(x);
以上函数的时间复杂度均为o(1)
2.bitset中常见的东西
bitset<1000>a;//长度为1000的bool数组
访问的话必须强转为int类型
比如(int)a[0],(int)a.any(),(int)a.count;
a.any();//判断存不存在至少一个1
a.none();//是不是全都是0
a.count();//统计这里面有几个1
a.set();//把所有数位都变成1
a.set(x);//把第x位变成1
a.reset(x);//把第x位变成0
a.reset();//把所有位变成0
找到第一个1的位置,和下一个1的位置

1.简单题

/*
正常思路:
dp[i][j]:表示前i个数,和为j的方案.
因为对于异或来说,一个数出现奇数次,那就相当于出现一次,出现偶数次就相当于没出现过
所以dp[i][j]:表示前i个数,和为j的方案数的奇偶性
复杂度是:
n*sum(a[i])=1000*2e6=2e9
考虑bitset优化?
首先考虑转移上怎么转换 
f[i][j]=(f[i-1][j-a[i]]+f[i-1][j])%2
相当于
f[i][j]=(f[i-1][j-a[i]]^f[i-1][j])
直接bitset即可
复杂度相当于是2e9/64 
*/

bitset<2000001>f;

void slove(){
	int n;cin>>n;
	f[0]=1;
	for(int i=0;i<n;i++){
		int x;cin>>x;
		f=f^(f<<x);
	}
	int ans=0;
	for(int i=0;i<=2000000;i++){
		if(f[i]) ans^=i;
	}
	cout<<ans<<endl;
} 

2.DAG计数

const int N=50010;

bitset<N>f[N];
vector<int>e[N];

void slove(){
	int n,m;cin>>n>>m;
	for(int i=1;i<=m;i++){
		int u,v;cin>>u>>v;
		e[u].push_back(v);
	}
	for(int u=n;u>=1;u--){
		f[u][u]=1;
		for(auto v:e[u]) f[u]|=f[v];
	}
	
	for(int i=1;i<=n;i++) {
		cout<<f[i].count()<<endl;
	}
} 
posted @ 2024-10-04 13:01  MENDAXZ  阅读(4)  评论(0编辑  收藏  举报