Codeforces 109D String Transformation 字符串 哈希 KMP

原文链接https://www.cnblogs.com/zhouzhendong/p/CF109D.html

题目传送门 - CF109D

题意

  给定两个字符串 $a,b$ ,求一组 $i,j$ 使得 $f(a,i,j)=b$ 。如果无解输出 "-1 -1" ,如果多组解,输出 i 尽量大的;如果 i 相同,输出 j 尽量小的。

  其中 $f(s,i,j) = s[i+1 cdots j-1] + r(s[0 cdots i]) + r(s[jcdots n-1])$ 。 $n$ 为串长。其中 $s[icdots j]$ 表示 串 $s$ 的 $i$ 至 $j$ 个位置构成的子串,+ 运算定义为字符串顺序拼接,$r(s)$ 表示 $s$ 翻转后得到的串。

  $|a|,|b| leq 10^6$

题解

  那个最大最小问题不大,我们来看看如何找一组解。

  首先,讲 a 串翻转。则问题变成了 $r(a[i+1]cdots a[j-1])+a[0cdots i] + a[jcdots n-1]=b$ 的 $(i,j)$ 。这个问题,只需要枚举 $j$ ,然后判定是否可以行即可。

  对于 $r(a[i+1]cdots a[j-1])$ 与 $b$ 的最大匹配长度,可以二分 + 哈希。

  对于以 b 串第 $j-1$ 个位置结尾的子串中与 $a$ 的前缀的匹配长度最大为多少,直接 KMP 。

  如果这两个长度大于 $j-1$ ,那么就可行。

  那个什么最大最小的,随便弄一弄就好了。

  注意我们求出来的翻转后的 a 串的答案,最后还要变换一下。

代码

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const int N=1000005*2;
char a[N],b[N];
int n,Next[N],len[N];
ULL Ha[N],Hb[N],Fac[N],T=233;
ULL Get_Hash(ULL *Ha,int L,int R){
	if (L>R)
		L=n*2-L+1,R=n*2-R+1;
	return Ha[R]-Ha[L-1]*Fac[R-L+1];
}
void KMP(char *a,char *b,int n){
	for (int i=2,k=0;i<=n;Next[i]=k+=(a[k+1]==a[i]),i++)
		while (k>0&&a[k+1]!=a[i])
			k=Next[k];
	for (int i=1,k=0;i<=n;len[i]=k+=(a[k+1]==b[i]),i++)
		while (k>0&&a[k+1]!=b[i])
			k=Next[k];
}
int Get(int j){
	int L=1,R=j-1,mid,k1=0;
	while (L<=R){
		mid=(L+R)>>1;
		if (Get_Hash(Hb,1,mid)==Get_Hash(Ha,j-1,j-mid))
			L=mid+1,k1=mid;
		else
			R=mid-1;
	}
	return k1+len[j-1]<j-1?-1:len[j-1];
}
int main(){
	gets(a+1),gets(b+1);
	n=strlen(a+1);
	if (strlen(b+1)!=n)
		return puts("-1 -1"),0;
	reverse(a+1,a+n+1);
	for (int i=n+1;i<=n*2;i++)
		a[i]=a[n*2-i+1],b[i]=b[n*2-i+1];
	KMP(a,b,n);
	for (int i=Fac[0]=1;i<=n*2;i++){
		Fac[i]=Fac[i-1]*T;
		Ha[i]=Ha[i-1]*T+a[i];
		Hb[i]=Hb[i-1]*T+b[i];
	}
	int ansi=10000000,ansj=10000000,d=-1;
	for (d=n;d>1;d--)
		if (a[d]!=b[d])
			break;
	for (int i=-1,j=d+1;j<=n&&!~i;j++)
		if (~(i=Get(j)))
			ansi=i,ansj=j;
	if (ansj==10000000)
		ansi=ansj=-1;
	else
		ansi=n-ansi,ansj=n-ansj;
	printf("%d %d
",ansj,ansi);
	return 0;
}

  

原文地址:https://www.cnblogs.com/zhouzhendong/p/CF109D.html