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

L e o n a r d o ′ s   N o t e b o o k Leonardo's\ Notebook Leonardos Notebook


D e s c r i p t i o n \mathcal{Description} Description
原序列为 { A , B , C . . . Y , Z } \{A,B,C...Y,Z\} {A,B,C...Y,Z},
请问有没有一种置换 T T T, 使得连续置换两次得到给出的序列 { X 1 , X 2 . . . X N } \{X_1,X_2...X_N\} {X1,X2...XN}.


S o l u t i o n \mathcal{Solution} Solution
<置换群快速幂运算研究与探讨>

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


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

  • T T T 的长度为奇数, 说明 g c d ( s i z e , k ) gcd(size,k) gcd(size,k) 1 1 1, 则 T T T 长度不变, 顺序可能会变, 但仍然是一个循环节.
  • T T T 的长度为偶数, 说明 g c d ( s i z e , j ) gcd(size, j) gcd(size,j) 2 2 2, 则 T T T 长度减半, 相当于分裂为两个新的循环节.

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


C o d e \mathcal{Code} 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值