【题解】Codeforces1523D Love-Hate

Codeforces1523D Love-Hate

题意

\(n\)个集合与和一个有\(m\)个元素的全集\(U\),每个集合都是\(U\)的子集,且每个集合大小不超过\(p\),求一个最大的\(U\)的子集\(A\),使得\(A\)至少是\(n\)个集合中\(\lceil \frac{n}{2}\rceil\)个集合的子集。

\(1\le n\le 2\times10^5,1\le p\le m\le 60,1\le p\le 15\)

题解

#include <bits/stdc++.h>
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int N=3e5+10,INF=1<<30;
int n,m,p=0,c[N],aa[N],res[62];
char s[75]; 
int pc[(1<<15)+10];
void fwtand(ll *a,int n,int typ){
	for(int mid=1;mid<n;mid<<=1){
		for(int r=(mid<<1),j=0;j<n;j+=r){
			for(int i=0;i<mid;i++){
				a[i+j]=(a[i+j]+typ*a[i+j+mid]);
			}
		}
	}
}
ll ov[N];
ll a[(1<<15)+10];
unsigned sd=chrono::system_clock::now().time_since_epoch().count();
mt19937 rndnum(sd);
int rnd(int n){
	unsigned res=rndnum()%n+1;
	return res;
}
int vis[N];
void f1(){
	for(int i=1,l=(1<<15);i<l;i++)pc[i]=pc[i>>1]+(i&1);
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1;i<=n;i++){
		//aa[i]=i;
		vis[i]=0;
		scanf("%s",s+1);
		for(int j=1;j<=m;j++){
			if(s[j]==‘1‘){ov[i]|=(1ll<<(j-1));}
		}
	}
	int ans=0;
	for(int o=1;o<=min(200,n);o++){
		int u=rnd(n);
		while(vis[u]){
			u=rnd(n);
			//assert(u<=n&&u>=1);
		}
		vis[u]=1;
		ll na=ov[u];p=0;
		for(int i=1;i<=m;i++){
			if((1ll<<(i-1))&na){c[++p]=i;}
		}
		memset(a,0,sizeof(a));
		for(int i=1;i<=n;i++){
			ll y=(na&ov[i]),z=0;
			for(int j=1;j<=p;j++){
				if((1ll<<(c[j]-1))&y){
					z|=(1<<(j-1));
				}
			}
			++a[z];
		}
		int l=(1<<p);
		fwtand(a,l,1);
		for(int i=0;i<l;i++)if(a[i]*2>=n&&pc[i]>ans){
			ans=pc[i];
			memset(res,0,sizeof(res));
			for(int j=1;j<=p;j++)if(i&(1<<(j-1))){
				res[c[j]]=1;
			}	
		}
	}
	for(int i=1;i<=m;i++){printf("%d",res[i]);}
}
int main(){
	//int t;
	//scanf("%d",&t);
	//while(t--)
		f1();
	return 0;
}
/*
3 4 3
1000
0110
1001

*/

【题解】Codeforces1523D Love-Hate

上一篇:常用的设计原则和设计模式


下一篇:require.context/