POJ 3128 Leonardo's Notebook[置换群幂相关]

Leonardos NotebookLeonardo's\ Notebook


Description\mathcal{Description}
原序列为 {A,B,C...Y,Z}\{A,B,C...Y,Z\},
请问有没有一种置换 TT, 使得连续置换两次得到给出的序列 {X1,X2...XN}\{X_1,X_2...X_N\}.


Solution\mathcal{Solution}
<置换群快速幂运算研究与探讨>

由这篇文章可以得到以下三个结论:


注意结论中的 TT循环节,
设 符合条件的置换 操作前其中一个循环节为 TT,
在这道题目中 指数kk22, 于是操作后

  • TT 的长度为奇数, 说明 gcd(size,k)gcd(size,k)11, 则 TT 长度不变, 顺序可能会变, 但仍然是一个循环节.
  • TT 的长度为偶数, 说明 gcd(size,j)gcd(size, j)22, 则 TT 长度减半, 相当于分裂为两个新的循环节.

所以在给出的序列中, 必须满足 长度为偶数且相等的循环节必须两两配对 才可能被 T2T^2 置换过来.


Code\mathcal{Code}

#include<cstdio>
#include<cstring>
#define reg register

int A[30];
int sum[30];

char S[30];

bool Used[30];

void Work(){
        scanf("%s", S+1);
        for(reg int i = 1; i <= 26; i ++) A[i] = S[i]-'A'+1;
        memset(Used, 0, sizeof Used);
        memset(sum, 0, sizeof sum);
        for(reg int i = 1; i <= 26; i ++)
                if(!Used[A[i]]){
                        int to = A[i], len = 0;
                        while(!Used[to]) Used[to] = 1, len ++, to = A[to];
                        sum[len] ++;
                }
        for(reg int i = 1; i <= 13; i ++)
                if(sum[i<<1] & 1){ printf("No\n"); return ; }
        printf("Yes\n");
}

int main(){
        int T;
        scanf("%d", &T);
        while(T --) Work();
        return 0;
}

posted @ 2019-06-30 23:37  XXX_Zbr  阅读(93)  评论(0编辑  收藏  举报