群论:循环的平方 循环元素为偶数的循环节必须为偶数
题目大意:给出一个A~Z的置换,问是否可以被表示为一个置换的平方(即G=G'*G')。
通过观察可以发现,一个置换乘上它本身,其中长度为偶数的循环节必然会分裂为两个长度相等的循环节,长度为奇数的循环节还是一个循环节,长度不变。如:
2341*2341=3412 (2341是一个循环节,平方后分裂为两个长度为2的循环节[13][24])
23451*23451=34512 (23451是一个循环节,平方后还是长度为5的循环节)
所以,给出的置换中长度为偶数的循环节必然是原置换中的循环节分裂出来的,而长度为奇数的循环节有可能是原置换中的循环节分裂出来的。因为只要判断能否被表示,所以可以忽略长度为奇数的循环节,只对长度为偶数的循环节进行考虑即可。
因为一个长度为偶数的循环节分裂出来的两个循环节的长度相等且同为原循环节长度的一半。所以,只要给出置换中所包含的长度为偶数的循环节能一一配对,那么就必然可以被表示为另一个置换的平方。
关键:循环元素为偶数的循环节必须为偶数。
1 //#include<bits/stdc++.h> 2 #include<iostream> 3 #include<cstdio> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 #include<cstring> 8 #define mp make_pair 9 #define pb push_back 10 #define first fi 11 #define second se 12 #define pw(x) (1ll << (x)) 13 #define sz(x) ((int)(x).size()) 14 #define all(x) (x).begin(),(x).end() 15 #define rep(i,l,r) for(int i=(l);i<(r);i++) 16 #define per(i,r,l) for(int i=(r);i>=(l);i--) 17 #define FOR(i,l,r) for(int i=(l);i<=(r);i++) 18 #define eps 1e-9 19 #define PIE acos(-1) 20 #define cl(a,b) memset(a,b,sizeof(a)) 21 #define fastio ios::sync_with_stdio(false);cin.tie(0); 22 #define lson l , mid , ls 23 #define rson mid + 1 , r , rs 24 #define ls (rt<<1) 25 #define rs (ls|1) 26 #define INF 0x3f3f3f3f 27 #define LINF 0x3f3f3f3f3f3f3f3f 28 #define freopen freopen("in.txt","r",stdin); 29 #define cfin ifstream cin("in.txt"); 30 #define lowbit(x) (x&(-x)) 31 #define sqr(a) a*a 32 #define ll long long 33 #define ull unsigned long long 34 #define vi vector<int> 35 #define pii pair<int, int> 36 #define dd(x) cout << #x << " = " << (x) << ", " 37 #define de(x) cout << #x << " = " << (x) << "\n" 38 #define endl "\n" 39 using namespace std; 40 //********************************** 41 int n; 42 //********************************** 43 char s[30]; 44 bool vis[30]; 45 int cnt[30]; 46 //********************************** 47 int main() 48 { 49 int T; 50 scanf("%d",&T); 51 while(T--){ 52 cl(cnt,0);cl(vis,0); 53 scanf("%s",s); 54 rep(i,0,26){ 55 if(!vis[i]){ 56 int j=i,n=0; 57 do{ 58 vis[j]=1; 59 j=s[j]-'A'; 60 n++; 61 }while(j!=i); 62 cnt[n]++; 63 } 64 } 65 int ok=1; 66 for(int i=2;i<=26;i+=2)if(cnt[i]&1)ok=0; 67 if(ok)puts("Yes"); 68 else puts("No"); 69 } 70 return 0; 71 }