bitset

bitset

CF113C Double Happiness

把线性筛的mindiv替换为bitset

#include <bitset>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;
const int N=300000005;
int n,l,r;
int p[20000005];
bitset<N>mindiv;

signed main() {
	scanf("%d%d",&l,&r);
	for(int i=2;i<=r;i++) {
		if(!mindiv[i]) mindiv[i]=1,p[++p[0]]=i;
		for(int j=1;j<=p[0]&&1ll*i*p[j]<=N;j++) {
			mindiv[i*p[j]]=1;
			if(i%p[j]==0) break;
		}
	}
	int ans=0;
	for(int i=1;i<=p[0];i++) 
		if(l<=p[i]&&p[i]<=r&&((p[i]-1)%4==0))
			ans++;
	if(l<=2&&2<=r) ans++;
	printf("%d\n",ans);
	return 0;
}


BZOJ3687: 简单题(dp+bitset)

求n个数子集算术和的异或和。

设dp[i]表示由这n个数能有多少种方案组成i,显然这样dp[1~sum]就将所有的子集和统计完了,只要判断(dp[i]&1)就有ans^=i

https://blog.csdn.net/Fsss_7/article/details/50822026

#include<cstdio>
#include<iostream>
#include<bitset>
#include<cstring>
using namespace std;
int N;
bitset<2000001>bit;
int main()
{
    scanf("%d",&N);
    bit[0]=1;
    while(N--)
    {
        int x;
        scanf("%d",&x);
        bit^=bit<<x;
    }
    int ans=0;
    for(int i=2000000;i>=0;i--)
        if(bit[i]==1) 
            ans^=i;
    printf("%d",ans);
    return 0;
}

[BZOJ4484: Jsoi2015]最小表示

#include <queue>
#include <cstdio>
#include <bitset>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
inline int read() {
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}
const int N=30005;
const int M=100005;

int n,m;
bitset<N>G[N];//维护连通性
int hd[N],to[M],nxt[M],tot;
inline void add(int x,int y) {
	to[++tot]=y;nxt[tot]=hd[x];hd[x]=tot;
}

int du[N];
int out[N],tim[N],cnt;//出队元素,时间
queue<int>q;
void topo() {
	for(int i=1;i<=n;i++)
		if(!du[i]) q.push(i);
	while(q.size()) {
		int x=q.front();
		q.pop();
		out[++cnt]=x;tim[x]=cnt;
		for(int i=hd[x];i;i=nxt[i]) 
			if(!(--du[to[i]])) 
				q.push(to[i]);
	}
}

int st[N],tp;
bool cmp(int a,int b) {
	return tim[a]<tim[b];
}
int ans;
int main() {
	n=read();m=read();
	for(int i=1,x,y;i<=m;i++) {
		x=read();y=read();
		add(x,y);du[y]++;
	}
	topo();
	//正着无法知道连通性,所以倒序处理
	for(int j=n;j;j--) {
		int x=out[j];
		G[x][x]=1;
		tp=0;
		for(int i=hd[x];i;i=nxt[i])
			st[++tp]=to[i];
		sort(st+1,st+1+tp,cmp);
		for(int i=1;i<=tp;i++) {
			if(G[x][st[i]]) ans++;
			else G[x]|=G[st[i]];
		}
	}
	printf("%d\n",ans);
	return 0;
}

联通数(传递闭包)

#include <bitset>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
inline int read() {
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}
int n;
bitset<2005>f[2005];
char mp[2005];
int main() {
	n=read();
	for(int i=1;i<=n;i++) {
		scanf("%s",mp+1);
		for(int j=1;j<=n;j++)
			f[i][j]=mp[j]-'0';
		f[i][i]=1;
	}
	for(int i=1;i<=n;i++) 
		for(int j=1;j<=n;j++)
			if(f[j][i])
				f[j]|=f[i];
	long long ans=0;
	for(int i=1;i<=n;i++) 
		ans+=f[i].count();
	printf("%lld\n",ans);
	return 0;
}
posted @ 2020-10-25 15:02  ke_xin  阅读(27)  评论(0编辑  收藏  举报