题意:
给你一个字符串s,让你求串A和B
1.|A|=|B|
2.s=AAA…AAABBB…BBBAAA…AAAa(n个A,m个B,k个A,|a|<|A|)n,m,k>0
题解:
A的长度和B相等,那么就很好做了,首先可以想到的是调和级数。
那么枚举长度,检查接下来是否是ABA这种出现形式,f就表示当前是A还是B。如果到了结尾并且f=1的话,就说明最后k个A没有出现。使用了双哈希
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define pl pair<ull,ull>
const int N=8e5+5;
pl h[N],p[N];
pl get_hash(int l,int r)
{
return (pl){h[r].first-h[l].first*p[r-l].first,h[r].second-h[l].second*p[r-l].second};
}
char s[N];
int main(){
scanf("%s",s+1);
int n=strlen(s+1);
p[0]={1,1};
for(int i=1;i<=n;i++){
p[i]={p[i-1].first*23ll,p[i-1].second*31ll};
h[i]={h[i-1].first*23ll+(ull)s[i],h[i-1].second*31ll+(ull)s[i]};
}
pl a,b;
int p=0;
for(int i=1;i<=n;i++){
a=get_hash(0,i);
b={0,0};
p=0;
int f=0;
int j;
for(j=i+1;j<=n;j+=i){
if(n-j+1<i){
if(f==1)break;
if(b.first==0&&b.second==0)b=a,p=1;
for(int k=1;k<=i;k++)
printf("%c",s[k]);
printf(" ");
for(int k=p;k<=p+i-1;k++)
printf("%c",s[k]);
return 0*printf("\n");
}
pl v=get_hash(j-1,j+i-1);
if(f==0){
if(v.first==a.first&&v.second==a.second)continue;
if(b.first==0&&b.second==0){
b=v;
p=j;
f=1;
continue;
}
break;
}
else {
if(v.first==b.first&&v.second==b.second)continue;
else if(v.first==a.first&&v.second==a.second){
f=0;
continue;
}
else break;
}
}
if(j>n&&f==0){
if(b.first==0&&b.second==0)b=a,p=1;
for(int k=1;k<=i;k++)
printf("%c",s[k]);
printf(" ");
for(int k=p;k<=p+i-1;k++)
printf("%c",s[k]);
return 0*printf("\n");
}
}
return 0;
}