Examples

CFgym102439 做题记录

jiangly哥哥的题解

C 题还不会做/ll。

难度排序:FEHKBJAGLDIC。

B Varvara and matrix

题意:定义一个矩阵的美丽值为四个顶点数字相同的子矩阵数量,现在给定一个 \(n\times m\) 的矩阵,你需要把所有的数字 \(0\) 替换成 \(a\)\(b\) 使得美丽值不变,给出一组构造方案或者报告无解。(\(2\leqslant n,m\leqslant 10^3\),每行每列至多有一个 \(0\)

比较套路的题。

首先不难发现这个美丽值没啥用,你只需要使得不增加新的顶点全 \(a/b\) 子矩阵就好了。

考虑对于每个 \(0\) 位置 2-SAT,那么我们发现限制只有两种:某个位置不能为 \(a/b\),某个位置不能喝另一个位置同时为 \(a/b\)

某个位置不能为 \(a/b\) 的限制可以用 bitset 优化,那么时间复杂度为 \(O(\frac{n^3}{\omega})\)

#include<stdio.h>
#include<bitset>
#include<vector>
using namespace std;
const int maxn=1005,maxN=maxn*4;
int n,m,k,a,b,top,tot,zs;
int s[maxn][maxn],vis[maxN],stk[maxN],bel[maxN];
bitset<maxn>A[maxn],B[maxn];
vector<int>v[maxN],rv[maxN];
vector< pair<int,int> >z;
inline void add(int x,int y){
	v[x].push_back(y),rv[y].push_back(x);
}
void dfs(int x){
	vis[x]=1;
	for(int i=0;i<v[x].size();i++)
		if(vis[v[x][i]]==0)
			dfs(v[x][i]);
	stk[++top]=x;
}
void rdfs(int x,int c){
	vis[x]=1,bel[x]=c;
	for(int i=0;i<rv[x].size();i++)
		if(vis[rv[x][i]]==0)
			rdfs(rv[x][i],c);
}
void kosaraju(){
	for(int i=1;i<=zs*2;i++)
		vis[i]=0;
	for(int i=1;i<=zs*2;i++)
		if(vis[i]==0)
			dfs(i);
	for(int i=1;i<=zs*2;i++)
		vis[i]=0;
	for(int i=zs*2;i>=1;i--)
		if(vis[stk[i]]==0)
			tot++,rdfs(stk[i],tot);
}
int main(){
	scanf("%d%d%d%d%d",&n,&m,&k,&a,&b); 
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			scanf("%d",&s[i][j]);
			if(s[i][j]==0)
				z.push_back(make_pair(i,j));
			if(s[i][j]==a)
				A[i][j]=1;
			if(s[i][j]==b)
				B[i][j]=1;
		}
	zs=z.size();
	for(int i=1;i<=zs;i++){
		int x=z[i-1].first,y=z[i-1].second;
		for(int j=1;j<=n;j++){
			if(A[j][y]&&(A[x]&A[j]).count())
				add(i,zs+i);
			if(B[j][y]&&(B[x]&B[j]).count())
				add(zs+i,i);
		}
	}
	for(int i=1;i<=zs;i++)
		for(int j=1;j<=zs;j++){
			int a=z[i-1].first,b=z[i-1].second,c=z[j-1].first,d=z[j-1].second;
			if(A[a][d]&&A[c][b])
				add(i,zs+j),add(j,zs+i);
			if(B[a][d]&&B[c][b])
				add(zs+i,j),add(zs+j,i);
		}
	kosaraju();
	for(int i=1;i<=zs;i++){
		if(bel[i]==bel[zs+i]){
			puts("No");
			return 0;
		}
		int x=z[i-1].first,y=z[i-1].second;
		s[x][y]=bel[i]>bel[zs+i]? a:b;
	}
	puts("Yes");
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			printf("%d%c",s[i][j],j==m? '\n':' ');
	return 0;
}

C Cockroach Racing

题意:

L The only winner

我们先考虑配对后最大值小于等于 \(m\) 的方案数,那么所有 \([\lceil\frac{m}{2}\rceil,2n]\) 内的数必须配对到一个 \([1,\lfloor\frac{m}{2}\rfloor]\) 内的数,其他的位置可以随意配对,那么方案数为,那么式子为:(设 \(k=\lfloor\frac{m}{2}\rfloor\)

posted @ 2021-09-05 18:21  xiaoziyao  阅读(73)  评论(0编辑  收藏  举报