题意:给出一个置换B,问有没有一个置换A,使得A^2=B。
思路:对于置换的循环节,比如(a1,a2,a3)和(b1,b2,b3,b4),那么对于奇数长度的循环节,发现进行两次乘法以后还是奇数长度,偶数长度的循环节分解为两个长度相同的循环节。那么就可以对B中的循环节进行判断,奇数长度的不同管,这个总能找到满足要求的,偶数循环节的数量也要是偶数,这样才能两两配对。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=26;
char str[maxn+10];
int cnt[maxn+10];
bool vis[maxn+10];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",str);
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
int tmp;
for(int i=0;i<maxn;++i)
{
if(vis[i]) continue;
tmp=0;
int j=str[i]-'A';
while(!vis[j])
{
vis[j]=true;
j=str[j]-'A';
tmp++;
}
cnt[tmp]++;
}
bool flag=true;
for(int i=0;i<maxn;i+=2)
if(cnt[i]&1) flag=false;
if(flag) puts("Yes");
else puts("No");
}
return 0;
}