Codeforces 765D Artsem and Saunders(数学)
2017-02-14 22:19
441 查看
题目地址:http://codeforces.com/contest/765/problem/D
思路:
g(h(x))=x 1<=x<=m (1)
h(g(x))=f(x) 1<=x<=n (2)
由(2)得h(g(h(x)))=f(h(x)),由(1)得h(g(h(x)))=h(x),则h(x)=f(h(x)) (3)
同理,由(1)得,g(h(g(x)))=g(x),由(2)得,g(h(g(x)))=g(f(x)),则g(x)=g(f(x)) (4)
所以,由(3)式,可得出g[i]的值:由此利用并查集,将x与f(x)合并,则若x的根节点为j(初始g全为-1),若j为-1则g[i]=g[j]=++cnt,否则g[i]=g[j]。也即将其依次赋值为1,2,3,.....。则由(3)式可由g数组的值计算出h数组的值,m也即为g数组中最大值。若计算h数组值时,若h[g[i]]无值,则将其赋为f[i],若其已有值且不等于f[i],则此时无解。将h数组赋值结束后,继续检查其是否满足g[h[i]]==i,若不满足,则无解,否则即得到一组解。
思路:
g(h(x))=x 1<=x<=m (1)
h(g(x))=f(x) 1<=x<=n (2)
由(2)得h(g(h(x)))=f(h(x)),由(1)得h(g(h(x)))=h(x),则h(x)=f(h(x)) (3)
同理,由(1)得,g(h(g(x)))=g(x),由(2)得,g(h(g(x)))=g(f(x)),则g(x)=g(f(x)) (4)
所以,由(3)式,可得出g[i]的值:由此利用并查集,将x与f(x)合并,则若x的根节点为j(初始g全为-1),若j为-1则g[i]=g[j]=++cnt,否则g[i]=g[j]。也即将其依次赋值为1,2,3,.....。则由(3)式可由g数组的值计算出h数组的值,m也即为g数组中最大值。若计算h数组值时,若h[g[i]]无值,则将其赋为f[i],若其已有值且不等于f[i],则此时无解。将h数组赋值结束后,继续检查其是否满足g[h[i]]==i,若不满足,则无解,否则即得到一组解。
#include<set> #include<map> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=1e5+50; const int INF=0x3f3f3f3f; int n; int h[maxn]; int g[maxn]; int f[maxn]; int fa[maxn]; int Find(int x) { return fa[x]==x?x:fa[x]=Find(fa[x]); } int main() { int cnt=0; scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&f[i]); for(int i=1; i<=n; i++) fa[i]=i; memset(g,-1,sizeof(g)); memset(h,-1,sizeof(h)); for(int i=1; i<=n; i++) { int xx=Find(i),yy=Find(f[i]); if(xx!=yy) { fa[xx]=yy; } } for(int i=1; i<=n; i++) { if(g[Find(i)]==-1) g[i]=g[Find(i)]=++cnt; else g[i]=g[Find(i)]; } int flag=1; for(int i=1; i<=n; i++) if(h[g[i]]==-1) { h[g[i]]=f[i]; } else if(h[g[i]]!=f[i]) { flag=0; break; } if(!flag) printf("-1\n"); else { int m=0; for(int i=1; i<=n; i++) m=max(m,g[i]); for(int i=1; i<=m; i++) { if(g[h[i]]!=i) { flag=0; break; } } if(!flag) printf("-1\n"); else { printf("%d\n",m); for(int i=1; i<=n; i++) { if(i==1) printf("%d",g[i]); else printf(" %d",g[i]); } printf("\n"); for(int i=1; i<=m; i++) { if(i==1) printf("%d",h[i]); else printf(" %d",h[i]); } printf("\n"); } } return 0; }
相关文章推荐
- 【CodeForces 765D】 Artsem and Saunders(数学,构造)
- Codeforces 765D Artsem and Saunders 构造
- Codeforces_765_D. Artsem and Saunders_(数学)
- codeforces 765D. Artsem and Saunders
- 【codeforces 765D】Artsem and Saunders
- Codeforces 765D Artsem and Saunders 【构造】
- Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) D. Artsem and Saunders 数学 构造
- 【Codeforces 756 D. Artsem and Saunders】+ 思维 + 构造
- codeforces 397div2 D Artsem and Saunders
- codeforces 397div2 D Artsem and Saunders
- codeforces 397div2 D Artsem and Saunders
- codeforces 397div2 D Artsem and Saunders
- D. Artsem and Saunders----数学思维
- codeforces 765 D Artsem and Saunders(构造)
- Codeforces Round #397(Div. 1 + Div. 2 combined)D. Artsem and Saunders【思维+乱搞】
- D. Artsem and Saunders
- D. Artsem and Saunders
- D. Artsem and Saunders
- D. Artsem and Saunders
- 【构造】Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) D. Artsem and Saunders