zoukankan      html  css  js  c++  java
  • 某考试 T1 str

         一开始死磕sam,发现根本没法做。。。。。。

         后来想了想,反正匹配子串的大部分不是sam就是 二分+hash啊,,,于是就想了想二分+hash,发现好像可以做啊!

         就是假设我们要让 s1[1] 映射到s2 中的位置是 s2[i] ,那么这种情况的答案就很好算了,就是求一次lcp之后把第一个不匹配的钦定成匹配之后再一次lcp。

        所以总的时间复杂度就是 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,ans;
    
    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
    ",ans);
    	return 0;
    }
    

      

         

        

  • 相关阅读:
    路由策略
    ospf 路由汇总
    OSPF type1 2
    ospf
    TCP 六种标识位
    raid 10 与 01
    SNMP协议
    ffmpeg剪切视频
    ubuntu18安装sbt
    服务器Ubuntu18重启后宝塔访问不了
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8974254.html
Copyright © 2011-2022 走看看