刚开始一直把题意看错了。。。体测完智商急剧下降
正确理解题意以后自己写一直wa,而且并不知道是哪里的问题,在网上看了一下其他人写的改了改自己的就过了,可是之前的还是不知道为什么不对。
题意大概就是有一个置换群,问运算多少次会出现给定的样子。我们可以求出每个元素需要运算多少次到达给定的样子,记为r[i]r[i]r[i],再计算出运算多少次是一个循环,记为m[i]m[i]m[i],则最后的次数x为x%m=r的同余方程的解。
AC代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<ctime>
#include<climits>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;typedef long long ll;
const ll INF=0x3f3f3f3f;
const ll MAXN=1e3+5;ll a[MAXN],b[MAXN],m[MAXN],r[MAXN],vis[MAXN],tmp[MAXN],nxt[MAXN];
ll n,ans;void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y)
{if(!b) {d=a; x=1; y=0;}else{ex_gcd(b,a%b,d,y,x); y-=(a/b)*x;}
}bool ex_crt(ll &M,ll &R)
{M=1; R=0; ll d,k,kk,c;for(ll i=1;i<=n;i++){if(m[i]==0 && r[i]==0) continue;c=r[i]-R;ex_gcd(M,m[i],d,k,kk);if(c%d) return false;k=c/d*k%(m[i]/d); R+=k*M; M*=m[i]/d; R%=M;}R=(R+M)%M;return true;
}void test()
{printf("============================\n");printf("m: "); for(ll i=1;i<=n;i++)printf("%d ",m[i]); printf("\n");printf("r: "); for(ll i=1;i<=n;i++)printf("%d ",r[i]); printf("\n");printf("============================\n");
}bool solve()
{ll t,cnt;memset(m,0,sizeof(m));memset(r,-1,sizeof(r));/*for(ll i=1;i<=n;i++){cnt=0; t=i;if(a[i]==i){if(b[i]!=i) return false;m[i]=0; r[i]=0; continue;}while(a[t]!=i){if(r[i]==-1 && t==b[i]) r[i]=cnt;t=a[t]; cnt++;}m[i]=cnt+1; if(r[i]==-1) return false;}*/memset(vis,false,sizeof(vis));for(int i=1;i<=n;i++) tmp[i]=i;cnt=0;while(cnt!=n){for(int i=1;i<=n;i++){nxt[i]=tmp[a[i]]; if(vis[i]) continue;m[i]++;if(nxt[i]==i){cnt++; vis[i]=true;}if(nxt[i]==b[i]) r[i]=m[i];}for(int i=1;i<=n;i++) tmp[i]=nxt[i];}for(int i=1;i<=n;i++){if(r[i]<0) return false; r[i]%=m[i];}//test();ll M,R;if(ex_crt(M,R))ans=R;else return false;return true;
}int main()
{while(~scanf("%lld",&n) && n){bool flag=true;for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);for(ll i=1;i<=n;i++) {scanf("%lld",&b[i]);if(flag && b[i]!=flag) flag=false;}if(flag){printf("0\n");continue;}if(solve()){printf("%lld\n",ans);}else{printf("-1\n");}}return 0;
}
我自己写的代码是求m和r的部分有问题,并不知道为什么。。。难受