zoukankan      html  css  js  c++  java
  • PA 2012 Final Round tas题解

    题目大意:每组数据共有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             else
    130             {
    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
  • 相关阅读:
    DataGridView 设置行不可见时,与货币管理器的位置关联的行不能设置为不可见
    DataGridView 冻结列后出现 无法添加该列,原因是它被冻结并被置于未冻结的列之后
    sql 2000 查询中增加序号列,自动增加列
    SQL 语法大全
    清除vs2003vs2008起始页最近打开项目
    ALTER TABLE 修改表时 因为有一个或多个对象访问此列
    UNIX上C++程序设计守则(信号和线程)(上)
    Thread Cancel 指南
    [C++再学习系列] 深入new/delete:New的3种形态
    设计模式学习(六):重构与模式,推荐书籍(完)
  • 原文地址:https://www.cnblogs.com/sillygirl/p/3911142.html
Copyright © 2011-2022 走看看