题意:
两个字符串s,t互为cyclical isomorphic,当且仅当s将前x个字符移到末尾后,s与t想等,例如s = abcde, t = deabc,那么s和t互为cyclical isomorphic。
给定一个s串,长度为n,k为n的因子,现在将s分成k个等长的字符串s1,s2,…sk,问是否存在一个t串,使得存在一个k,满足s1,s2,…,sk都和t互为cyclical isomorphic。
题解:
枚举k,将s分割成k串s1,s2,…,sk,设t=s1s1,即s1串复制一遍,跑KMP判断所有的子串是否包含于t串即可。
AC_CODE:
const int maxn = 1e7+5;
char s[maxn],t[maxn],temp[maxn];
int Next[maxn];
int lent;
int tt;
//求Next数组
void getNEXT(int x){ //获取next数组
Next[0]=-1;
int k=-1,j=0;
while(j<x){
if(k==-1||temp[j]==temp[k]){
k++;
j++;
if(temp[j]!=temp[k]) Next[j]=k;
else Next[j]=Next[k];
}
else k=Next[k];
}
}
int KMP(int x){ //kmp主要的还是next数组
int i=0,j=0;
getNEXT(x);
while(i<lent&&j<x){ //两个指针
if(j==-1||t[i]==temp[j]){
i++;
j++;
}
else{
j=Next[j];
}
}
if(j==x)return i-j+1;
else return -1;
}
void solve(){
ll n;
R(n);
scanf("%s",s);
if(n == 1) {
W("No");
return;
}
VL v;
for(ll k=1; k<n; ++k) {
if(n % k == 0) v.emplace_back(k);
}
bool ok = 0;
for(auto x: v) {
int cnt = 0;
for(int i=0; i<x; ++i) {
t[i] = s[i];
}
for(int i=x; i<2*x; ++i) {
t[i] = t[i-x];
}
lent = 2 * x;
for(int i=0; i<n/x; ++i) {
for(int j=i*x; j<i*x+x; ++j) {
temp[cnt++] = s[j];
}
cnt = 0;
int ans = KMP(x);
if(ans == -1) {
cnt = mod;
break;
}
}
if(cnt != mod) ok = 1;
}
if(ok) W("Yes");
else W("No");
}