《LGJOJ 8.24》 测试总结

这波贵物了属于是

\(T1\) 黑暗料理

奇偶分开,二分图,要用到 \(Miller\_Rabin\) 判素数。

点击查看代码
#include<bits/stdc++.h>
typedef long long LL;

using namespace std;
const int MAXN=760;
const LL inf=1e18;
int n,T,st,de;
int a[MAXN];
struct daduoli {
	int f,t,c;
}que[MAXN*MAXN*2];
int cnt=1,h[MAXN];
void add(int f,int t,int c) {
	que[++cnt].f=h[f];
	que[cnt].t=t;
	que[cnt].c=c;
	h[f]=cnt;
}
void adline(int x,int y,int w) {
	add(x,y,w);
	add(y,x,0);
}
int dis[MAXN],cur[MAXN];
bool bfs() {
	for(int i=1;i<=n+2;++i) {
		dis[i]=-2;
		cur[i]=h[i];
	}
	dis[st]=0;
	queue<int> q;
	q.push(st);
	while(!q.empty()) {
		int u=q.front();
		q.pop();
		for(int i=h[u];i;i=que[i].f) {
			int t=que[i].t;
			if(dis[t]==-2&&que[i].c) {
				dis[t]=dis[u]+1;
				q.push(t);
				if(t==de) return true;
			}
		}
	}
	return false;
}
LL dinic(LL u,LL flow) {
	if(u==de) return flow;
	LL res=0;
	for(int i=cur[u];i&&flow;i=que[cur[u]].f) {
		cur[u]=i;
		int t=que[i].t;
		if(!que[i].c||dis[u]+1!=dis[t]) continue;
		LL k=dinic(t,min(flow,(LL)que[i].c));
		if(!k) dis[t]=-2;
		flow-=k; res+=k;
		que[i].c-=k;
		que[i^1].c+=k;
	}
	return res;
}
int prime[10+10]={2,3,5,7,11,233,331},tim=7;
LL ksm(LL x,LL y,LL MODD) {
	LL ret=1;
	while(y) {
		if(y&1) ret=ret*x%MODD;
		x=x*x%MODD;
		y>>=1;
	}
	return ret;
}
LL mul(LL x,LL y,LL MODD) {
	LL ret=0;
	while(y) {
		if(y&1) ret=(ret+x)%MODD;
		x=(x+x)%MODD;
		y>>=1;
	}
	return ret;
}
bool miller_rabin(LL a,LL n) {
	LL s=n-1,r=0;
	while(!(s&1)) {
		s>>=1; 
		++r;
	}
	LL x=ksm(a,s,n);
	for(int i=0;i<r;++i) {
		LL tmp=mul(x,x,n);
		if(x!=1&&x!=n-1&&tmp==1) return false;
		x=tmp;
	}
	return (x==1);
}
bool check(int n) {
	if(n==1) return false;
	for(int i=0;i<tim;++i) {
		if(n==prime[i]) return true;
		if(!miller_rabin(prime[i],n)) {
			return false;
		}
	}
	return true;
}
int main() {
	scanf("%d",&T);
	while(T--) {
		cnt=1; memset(h,0,sizeof(h));
		scanf("%d",&n);
		st=n+1; de=n+2;
		for(int i=1;i<=n;++i) {
			scanf("%d",&a[i]);
		}
		bool sf=0;
		int ans=0;
		for(int i=1;i<=n;++i) {
			if(a[i]==1&&sf) {
				++ans;
				continue;
			}
			if(a[i]==1) sf=1;
			if(a[i]%2==1) adline(st,i,1);
			else adline(i,de,1);
			for(int j=i+1;j<=n;++j) {
				if(i==j) continue;
				if(check(a[i]+a[j])) {
					if(a[i]%2==1) adline(i,j,1);
					else adline(j,i,1);
				}
			}
		}
		while(bfs()) ans+=dinic(st,inf);
		printf("%d\n",n-ans);
	}
	return 0;
}

\(T2\) 爆炸

考虑并查集,如果 \((i,j)\) 有炸弹,就将第 \(i\) 行第 \(j\) 列连起来。

但是一次爆炸必须要一个炸弹来引燃,也就是说对于一般情况而言,要失去一个行或列的贡献,但是如果有环就是另一回事了,怎么判环呢,就是炸弹数量大于等于所能炸取的行列之和。

时间复杂度 \(O(nm)\)

点击查看代码
#include<bits/stdc++.h>
typedef long long LL;

using namespace std;
const int MAXN=6010;
int n,m,k,b,ans;
int fa[MAXN*2],sz[MAXN*2],du[MAXN];
char ch[3010][3010];
int find(int x) {
	return (fa[x]==x?x:fa[x]=find(fa[x]));
}
void merge(int x,int y) {
	int xx=find(x);
	int yy=find(y);
	if(xx==yy) return ;
	fa[yy]=xx;
	sz[xx]+=sz[yy];
	++sz[xx];
	++du[x]; ++du[y];
}
vector<int> e[MAXN];
int sf[MAXN];
int main() {
	scanf("%d%d%d%d",&n,&m,&k,&b);
	for(int i=1;i<=n;++i) {
		for(int j=1;j<=m;++j) {
			ch[i][j]=getchar();
			while(ch[i][j]!='k'&&ch[i][j]!='b'&&ch[i][j]!='.') ch[i][j]=getchar();
		}
	}
	for(int i=1;i<=n+m;++i) {
		fa[i]=i; sz[i]=0;
	}
	for(int i=1;i<=n;++i) {
		for(int j=1;j<=m;++j) {
			if(ch[i][j]=='b') {
				merge(i,n+j);
			}
		}
	}
	for(int i=1;i<=n+m;++i) {
		fa[i]=find(fa[i]);
		e[fa[i]].push_back(i);
	}
	for(int i=1;i<=n+m;++i) {
		int ls=0,p=0;
		if(fa[i]!=i) continue;
		for(auto t:e[i]) {
			++p;
			if(t<=n) {
				sf[t]=i;
				for(int j=1;j<=m;++j) {
					if(ch[t][j]=='k'&&sf[n+j]!=i) {
						++ls;
					}
				}
			}
			else {
				sf[t]=i;
				for(int j=1;j<=n;++j) {
					if(ch[j][t-n]=='k'&&sf[j]!=i) {
						++ls;
					}
				}
			}
		}
		if(sz[i]>=p) ans=max(ans,ls);
		for(auto t:e[i]) {
			if(du[t]>1) continue;
			int lss=ls;
			if(t<=n) {
				for(int j=1;j<=m;++j) {
					if(ch[t][j]=='k'&&sf[n+j]!=i) {
						--lss;
					}
				}
			}
			else {
				for(int j=1;j<=n;++j) {
					if(ch[j][t-n]=='k'&&sf[j]!=i) {
						--lss;
					}
				}
			}
			ans=max(ans,lss);
		}
	}
	printf("%d\n",ans);
	return 0;
}
posted @ 2023-08-24 19:40  daduoli  阅读(81)  评论(0)    收藏  举报