CF 1545 C AquaMoon and Permutations 题解

CF 1545 C AquaMoon and Permutations 题解

非常有意思的一题。

比赛的时候一直感觉这两个部分都是np,完全不可做。

后来才发现,只需要把确定的位置删掉,然后剩下的部分肯定构成二分图。然后直接黑白染色+二分图计数就好了。

#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
//    int x=0;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){
//        ch=getchar();
//    }
//    while(ch>='0'&&ch<='9'){
//        x=(x<<1)+(x<<3)+(ch^48);
//        ch=getchar();
//    }
//    return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int MAXN=505;
int t,n,a[MAXN<<1][MAXN];
bool era[MAXN<<1],cho[MAXN<<1];
int cnt[MAXN][MAXN];
int fa[MAXN<<1];
int root(int x){
	return fa[x]=(x==fa[x]? x:root(fa[x]));
}
vector<int> g[MAXN<<1];
bool col[MAXN<<1];
bool vis[MAXN<<1];
void dfs(int now){
	vis[now]=1;
	for(auto it:g[now]){
		if(!vis[it]){
			col[it]=col[now]^1;
			dfs(it);
		}
	}
}
void solve(){
	scanf("%d",&n);
	rb(i,1,n*2) rb(j,1,n) scanf("%d",&a[i][j]);
	memset(era,0,sizeof(era));
	memset(vis,0,sizeof(vis));
	memset(cho,0,sizeof(cho));
	memset(cnt,0,sizeof(cnt));
	memset(col,0,sizeof(col));
	rb(i,1,n*2) rb(j,1,n) cnt[j][a[i][j]]++;
	rb(T,1,n){
		mp Tmp=II(-1,-1);
		rb(j,1,n){
			rb(k,1,n) if(cnt[j][k]==1){
				Tmp=II(j,k);
				break;
			}
			if(Tmp.FIR!=-1) break;
		}
		if(Tmp.FIR==-1) break;
		int x;
		rb(j,1,2*n){
			if(!era[j]&&a[j][Tmp.FIR]==Tmp.SEC){
				x=j;
				break;
			}
		}
		cho[x]=1;
		rb(j,1,2*n) if(!era[j]&&j!=x){
			rb(k,1,n) if(j!=x&&a[j][k]==a[x][k]) era[j]=1;
			if(era[j]){
				rb(k,1,n) cnt[k][a[j][k]]--;
			}
		}
		rb(k,1,n) cnt[k][a[x][k]]--;
	}
	rb(i,1,n*2) g[i].clear(),fa[i]=i;
	rb(i,1,n*2) era[i]|=cho[i];
	rb(i,1,n*2) if(!era[i]) rb(j,i+1,n*2) if(!era[j]) {
		bool E=0;
		rb(k,1,n) if(a[i][k]==a[j][k]){
			E=1;
			break;
		}
		if(E){
			g[i].PB(j);
			g[j].PB(i);
			fa[root(i)]=root(j);
		}
	}
	rb(i,1,n*2) if(!era[i]&&!vis[i]) dfs(i);
	int ans=1;
	vector<int> res;
	rb(i,1,n*2){
		if(!era[i]&&col[i]==0){
			res.PB(i);
		}
	}
	rb(i,1,n*2) if(!era[i]&&root(i)==i) ans=(ans+ans)%998244353;
	rb(i,1,2*n) if(cho[i]) res.PB(i);
	printf("%d\n",ans);
	for(auto it:res){
		printf("%d ",it);
	}
	puts("");
}
int main(){
	scanf("%d",&t);
	while(t--) solve();
	return 0;
}
上一篇:罗丹明标记盐酸去氧肾上腺素|RB-葡萄糖氧化酶-齐岳科研


下一篇:源码中的超高性能取模