题解:AT_agc059_c [AGC059C] Guessing Permutation for as Long as Possible
[AGC059C] Guessing Permutation for as Long as Possible 题解
前言
题目传送门:AGC059C Guessing Permutation for as Long as Possible。
题面:问又多少种
这篇题解题只需要使用【模板】并查集。
思路
分析性质,如果
如果
这不正是并查集的合并操作吗?设
思路都到这里了,接下来统计方案数。如何判断答案为
最后时间复杂度
Code
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int MAXN = 400 + 3;
const LL mod = 1e9 + 7;
int n, vis[MAXN][MAXN];
int fa[MAXN * MAXN];
int Ri(int i, int j){ // (P_i < P_j) 这一节点的编号
return (i - 1) * n + j;
}
int Getf(int x){ return fa[x] == x ? x : fa[x] = Getf(fa[x]); }
void Merge(int x, int y){ x = Getf(x), y = Getf(y), fa[x] = y; }
int main(){
cin >> n;
for(int i = 1, a, b; i <= n * (n - 1) / 2; i++){
cin >> a >> b, vis[a][b] = vis[b][a] = i;
}
for(int i = 1; i <= n * n; i++) fa[i] = i;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
for(int k = 1; k <= n; k++){
if(vis[i][j] > vis[i][k] && vis[i][j] > vis[j][k]){
Merge(Ri(i,k), Ri(j,k)); // Pi < Pk <=> Pj < Pk
Merge(Ri(k,i), Ri(k,j)); // Pi > Pk <=> Pj > Pk
}
}
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(i != j && Getf(Ri(i,j)) == Getf(Ri(j,i))){
cout << 0; // 矛盾
return 0;
}
}
}
set<int> st;
LL ans = 1;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(i == j) continue;
int f = Getf(Ri(i,j)), _f = Getf(Ri(j,i));
if(st.find(f) == st.end()){ // set 去重
st.insert(f), st.insert(_f), ans = ans * 2ll % mod;
}
}
}
cout << ans;
return 0;
}
本文作者:hhhqx
本文链接:https://www.cnblogs.com/huangqixuan/p/18584541
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步