返回顶部

群论:循环的平方 循环元素为偶数的循环节必须为偶数

POJ3128

参考博客

题目大意:给出一个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 }
View Code

 

posted @ 2018-09-18 23:39  牛奶加咖啡~  阅读(472)  评论(0编辑  收藏  举报