A test T1 str

 

 

     At first, I stammered sam and found that I couldn't do it at all. . . . . .

     After thinking about it, anyway, most of the sam matching substrings are two points + hash, ,, so I thought about two points + hash, and found that it seems to be possible!

     It is assumed that the position where we want to map s1[1] to s2 is s2[i], then the answer in this case is very good, that is, after asking for an lcp, the first mismatch is determined as a match and then one lcp.

    So the total time complexity is O(N * log(N)).

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define ll unsigned long long
using namespace std;
const int maxn=140005,BASE=2875;
char s[maxn],S[maxn];
ll h[maxn],H[maxn],ci[maxn];
int n,m,years;

inline bool EQ(int b,int B,int len){
	if(b+len-1>n||B+len-1>m) return 0;
	return h [b + len-1] -h [b-1] * ci [len] == H [B + len-1] -H [B-1] * ci [len];
}

int main(){
	freopen("str.in","r",stdin);
	freopen("str.out","w",stdout);
	
	scanf("%s%s",s+1,S+1),ci[0]=1;
	n=strlen(s+1),m=strlen(S+1);
	s[n+1]='6',n++,S[m+1]='~',m++;
	
	for(int i=1;i<=n;i++) h[i]=h[i-1]*(ll)BASE+(ll)s[i];
	for(int i=1;i<=m;i++) H[i]=H[i-1]*(ll)BASE+(ll)S[i];
	for(int i=1;i<=max(n,m);i++) ci[i]=ci[i-1]*(ll)BASE;
	
	for(int i=1;i<=m;i++){
		int l=0,r=n,mid,an;
		while(l<=r){
			mid=l+r>>1;
			if(EQ(1,i,mid)) l=mid+1,an=mid;
			else r=mid-1;
		}
		
		if(an==n){
			ans = an;
			break;
		}
		
		l=0,r=n-an-1;
		while(l<=r){
			mid=l+r>>1;
			if(EQ(an+2,i+an+1,mid)) l=mid+1,ans=max(ans,an+mid+1);
			else r=mid-1;
		}
	}
	
	printf("%d\n",ans);
	return 0;
}

  

     

    

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325167052&siteId=291194637