• 【NOI模拟赛(湖南)】DeepDarkFantasy


    DeepDarkFantasy

    从东京出发,不久便到一处驿站,写道:日暮里。  ——鲁迅《藤野先生》

    定义一个置换的平方为对1~n的序列做两次该置换得到的序列。已知一个置换的平方,并且这个结果是一个排列,求该置换。

    输入第一行一个数n表示排列长度,接下来一行n个数描述排列。

    有解则输出一行n个数表示原排列。否则输出一行一个-1。

     

    测试点编号

    特征

    0~1

    n<=10

    2~9

    n<=1000000

    【题解】

    注:由于置换和排列在数学表现形式上是一样的,于是下文不对此进行详细区分。

    首先对于任意一个排列,我们都可以将其看作一个有向图,即若排列中第i个点为x,那么相应的图中就会有一条从i连向x的边。那么对于一个置换的平方所得到的置换,相当于如果原图中有一条从x到y的边和一条从y到z的边,那么在新图中就会有一条从x到z的边。通过观察发现,原图中只有环的奇偶性会对答案的构成方式产生影响,于是我们可以对奇环和偶环分别进行讨论得到答案。

    对于奇环的情况,可以令一个有5个点奇环为12345,那么在图中移动两步得到的图会是13524,那么如果中间有一个奇环的话,我们就可以按顺序遍历环的前一半和后一半得到原来的环。

    对于偶环的情况,假设有一个偶环为123456,那么最终的结果会是形成两个环135与246,那么我们每次可以每次去两个环的同一位置上的数接在一起得到原来的环。

    由于奇环所得到的答案一定是一个奇环,偶环得到的答案一定是两个长度相等的环,那么无解的情况就显然是新图中偶环的个数为奇数个。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<ctime>
     7 #include<algorithm>
     8 #include<vector>
     9 using namespace std;
    10 #define MAXN 1000100
    11 int n,len,a[MAXN],vis[MAXN],id[MAXN],ans[MAXN];
    12 vector<int> c[MAXN];
    13 inline int read()
    14 {
    15     int x=0,f=1;  char ch=getchar();
    16     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
    17     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
    18     return x*f;
    19 }
    20 bool cmp(int a,int b)
    21 {return c[a].size()<c[b].size();}
    22 void dfs(int x)
    23 {
    24     c[len].push_back(x);
    25     vis[x]=1;
    26     if(!vis[a[x]])  dfs(a[x]);
    27 }
    28 int main()
    29 {
    30     freopen("deepdarkfantasy.in","r",stdin);
    31     freopen("deepdarkfantasy.out","w",stdout);
    32     n=read();
    33     for(int i=1;i<=n;i++)  a[read()]=i;
    34     for(int i=1;i<=n;i++)
    35         if(!vis[i])  {len++;  dfs(i);}
    36     for(int i=1;i<=len;i++)  id[i]=i;
    37     sort(id+1,id+len+1,cmp);
    38     for(int i=1;i<=len;i++)
    39     {
    40         if(c[id[i]].size()&1)  //奇环
    41         {
    42             int mid=c[id[i]].size()>>1;
    43             mid++;
    44             for(int j=0;j<c[id[i]].size();j++)
    45                 ans[c[id[i]][j]]=c[id[i]][(j+mid)%c[id[i]].size()];
    46         }
    47         else  //偶环
    48         {
    49             if(c[id[i]].size()!=c[id[i+1]].size())
    50             {
    51                 printf("-1
    ");
    52                 return 0;
    53             }
    54             else
    55             {
    56                 for(int j=0;j<c[id[i]].size();j++)
    57                 {
    58                     ans[c[id[i]][j]]=c[id[i+1]][j];
    59                     ans[c[id[i+1]][j]]=c[id[i]][(j+1)%c[id[i]].size()];
    60                 }
    61                 i++;
    62             }
    63         }
    64     }
    65     for(int i=1;i<=n;i++)  printf("%d ",ans[i]);
    66     printf("
    ");
    67     return 0;
    68 }
    View Code

     

  • 相关阅读:
    吴裕雄--天生自然python学习笔记:Python3 MySQL 数据库连接
    吴裕雄--天生自然python学习笔记:Python MySQL
    吴裕雄--天生自然python学习笔记:Python CGI编程
    吴裕雄--天生自然python学习笔记:Python3 正则表达式
    一图解千言,从兴趣意念直达搜索目标!
    程序员如何让自己 Be Cloud Native
    当移动数据分析需求遇到Quick BI
    阿里云DMS发布数据库网关服务: 打通网络限制 开启数据库统一管理的万能钥匙
    阿里云重磅发布DMS数据库实验室 免费体验数据库引擎
    阿里云数据管理DMS企业版发布年度重大更新 多项功能全面升级
  • 原文地址:https://www.cnblogs.com/chty/p/5851119.html
Copyright © 2020-2023  润新知