CF119D
还是一道很综合的 string 练手题。
先来分析一下,将
第一段:
第二段:
第三段:
我们大概率是要枚举其中一个的,其中第三段都能用
下令
然后考虑怎样处理剩下的。发现此时第一段在
但是我没用 exkmp,用的是字符串 hash。
code:
点击查看代码
const int base[2]={13331,131313},mod[2]={(int)1e9+9,469762049};
int n,m,c[207][2],fail[N],pre[N],suf[N],f[N][2],g[N][2],pw[N][2];
char s[N],t[N],r[N];
mt19937 rnd(time(0));
void readStr(char *s,int &n){
char c=gc();
while(c<32||c>126)c=gc();
while(c>=32&&c<=126)s[++n]=c,c=gc();
}
il pair<ll,ll> getHashf(int l,int r){
if(l>r)return Mp(0,0);
return Mp((f[r][0]-1ll*f[l-1][0]*pw[r-l+1][0]%mod[0]+mod[0])%mod[0],(f[r][1]-1ll*f[l-1][1]*pw[r-l+1][1]%mod[1]+mod[1])%mod[1]);
}
il pair<ll,ll> getHashg(int l,int r){
if(l>r)return Mp(0,0);
return Mp((g[r][0]-1ll*g[l-1][0]*pw[r-l+1][0]%mod[0]+mod[0])%mod[0],(g[r][1]-1ll*g[l-1][1]*pw[r-l+1][1]%mod[1]+mod[1])%mod[1]);
}
void Yorushika(){
readStr(s,n),readStr(t,m);
if(n!=m){puts("-1 -1");return;}
rep(i,1,150)c[i][0]=c[i][1]=i;
pw[0][0]=pw[0][1]=1;
rep(i,1,n)rep(j,0,1){
f[i][j]=(1ll*f[i-1][j]*base[j]+c[s[i]][j])%mod[j];
g[i][j]=(1ll*g[i-1][j]*base[j]+c[t[i]][j])%mod[j];
pw[i][j]=1ll*pw[i-1][j]*base[j]%mod[j];
}
rep(i,1,n){
int l=0,r=n-i+1;
pre[i]=0;
while(l<=r){
int mid=(l+r)>>1;
if(getHashf(i,i+mid-1)==getHashg(1,mid))l=(pre[i]=mid)+1;
else r=mid-1;
}
}
rep(i,1,n)r[i]=s[n-i+1];
rep(i,2,n){
int &j=(fail[i]=fail[i-1]);
while(j&&r[i]!=r[j+1])j=fail[j];
j+=r[i]==r[j+1];
}
rep(i,1,n){
int &j=(suf[i]=suf[i-1]);
while(j&&t[i]!=r[j+1])j=fail[j];
j+=t[i]==r[j+1];
}
int p=0;
while(p<n&&s[p+1]==t[n-p])p++;
drep(i,min(p,n-1),1){
if(s[i]!=t[n-i+1])break;
if(pre[i+1]+suf[n-i]>=n-i)return printf("%d %d\n",i-1,n-suf[n-i]),void();
}
puts("-1 -1");
}
signed main(){
int t=1;
// scanf("%d",&t);
while(t--)
Yorushika();
}