首页 > 代码库 > PA 2012 求解判断置换A^k=B

PA 2012 求解判断置换A^k=B

题目大意:每组数据共有3行。

       第一行有一个正整数n。
       第二行有n个正整数A_1, A_2, ..., A_n表示置换A。
       第三行有n个正整数B_1, B_2, ..., B_n表示排列B。判断能否达到B。n<=1000000
思考过程:这道题也是模拟赛中遇到的,刚开始,很显然的想出了置换群,并且发现了几种可以达到的充分且必要条件(这里我们将b数组重新定义为i最后处在的位置)
(1)a,b必在一个置换群中
(2)x≡bi(mod ai)其中x为置换次数,ai,bi为每一个置换群的大小,和需要变换的最小次数
  到了这一步,就不知道怎么做了。。。。。。
看完标程后,终于知道了其中的奥秘
题解:将ai分解质因数,因为x mod ab=c可以推出x mod a=c mod a,所以,我们可以记录每一个质数的余数,再进行判断,首先要用线性筛求出每个数的最小质数(这样可以节约时间)然后再分解,具体看代码。
  1 #include<iostream>  2 #include<cstring>  3 #include<cmath>  4 #include<algorithm>  5 #include<cstdio>  6 using namespace std;  7 const int maxn=1000005;  8 int n;  9 int a[maxn]; 10 int f[maxn]; 11 int num[maxn]; 12 int all[maxn]; 13 int b[maxn]; 14 char tmp[20]; 15 int p[maxn]; 16 int col; 17 int t; 18 bool flag; 19 void read(int &x){ 20     char ch = getchar(); while (ch < 0 || ch > 9) ch = getchar(); 21     for (x = 0; ch >= 0 && ch <= 9; ch = getchar()) x = x*10+ch-48; 22 } 23 int gcd(int x,int y) 24 { 25     if(y==0)return x; 26     return gcd(y,x%y); 27 } 28 struct eq2{ int r, p, a; }e2[7100000]; 29 bool cmp(eq2 u,eq2 v) 30 { 31     if(u.p!=v.p)return u.p<v.p; 32     return u.a>v.a; 33 } 34 int l2; 35 int prm[11000000], lp; 36 int fac[11000000]; 37 void init(){ 38     for(int i=2;i<=1000000;i++){ 39         //cout<<i<<endl; 40         if (!fac[i]){ prm[++lp] = i; fac[i] = lp;} 41         for(int j=1;j<=lp;j++) 42         { 43             //cout<<"find"; 44             if (prm[j]*i > 1000000) break; 45             fac[prm[j]*i] = j; 46             if (fac[i] == j) break; 47         } 48     } 49 } 50 bool solve() 51 { 52     int l2=0; 53     for(int i=1;i<=col;i++) 54     { 55         int t=all[i]; 56         while(t!=1) 57         { 58             //cout<<t<<endl; 59             int ff=fac[t]; 60             //cout<<ff<<endl; 61             e2[++l2].p=ff; 62             e2[l2].a=1; 63             while(fac[t]==ff) 64             { 65                 t/=prm[ff]; 66                 e2[l2].a*=prm[ff]; 67             } 68             e2[l2].r=p[i]%e2[l2].a; 69              70         } 71     } 72 //    cout<<l2<<endl; 73     sort(e2+1,e2+l2+1,cmp); 74     for(int i=1;i<l2;i++) 75     { 76         if(e2[i].p==e2[i+1].p) 77         { 78             if (e2[i].r%e2[i+1].a != e2[i+1].r){return false;} 79         } 80     } 81     return true; 82 } 83 int main() 84 { 85 //    freopen("ever.in","r",stdin); 86 //    freopen("ever.out","w",stdout); 87     init(); 88    // cout<<fac[4]<<endl; 89     while(scanf("%d",&n)!=EOF) 90     { 91         gets(tmp); 92         flag=true; 93         for(int i=1;i<=n;i++) 94        read(a[i]); 95         memset(f,0,sizeof(f)); 96         memset(p,0,sizeof(p)); 97         col=0; 98         for(int i=1;i<=n;i++) 99         {100             if(f[i])continue;101             f[i]=++col;102             t=1;103             num[i]=t;104             int j=a[i];105             while(!f[j])106             {107                 t++;108                 num[j]=t;109                 f[j]=col;110                 j=a[j];111             }112             all[col]=t;113         }114         for(int i=1;i<=n;i++)115         {116             int x;117             read(x);118             b[x]=i;119         }120         for(int i=1;i<=n;i++)121         {122             int x=b[i];123             //cout<<i<<" "<<x<<endl;124             if(f[i]!=f[x])125             {126                 flag=false;127                 128             }129             else130             {131                 if(!p[f[i]])132                 {133                     p[f[i]]=(num[x]-num[i]+all[f[i]])%all[f[i]];134                 }135                 else 136                 {137                     if((num[x]-num[i]+all[f[i]])%all[f[i]]!=p[f[i]])138                     {139                         flag=false;140                     }141                 }142             }143         }144       //  for(int i=1;i<=col;i++)cout<<p[i]<<" "<<all[i]<<endl;145         if(!flag){puts("Forever");continue;}146         if(solve())puts("Ever");else puts("Forever");147     }148     return 0;149 }
View Code