• BZOJ 4032: [HEOI2015]最短不公共子串(后缀自动机+记忆化搜索)


    传送门

    解题思路

      首先需要预处理两个串(nxt(i)(j))表示i位置之后最近的(j)
      第一问直接对(b)建后缀自动机,枚举(a)的起点暴力匹配。
      第二问枚举(a)的起点,(b)(nxt)跳。
      第三问(a)(b)一起跳,(b)用后缀自动机,(a)(nxt)
      第四问(a)(b)一起跳,都用(nxt),要加记忆化。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    
    using namespace std;
    const int N=2005;
    
    inline int min(int x,int y) {return x<y?x:y;}
    
    int lena,lenb,ans=1e9,nxta[N][27],prea[27],nxtb[N][27],preb[27];
    int vis[N][N];
    char A[N],B[N];
    
    struct SAM{
    	int lst,cnt,fa[N<<1],ch[N<<1][27],l[N<<1];
    	inline void insert(int c){
    		int p=lst,np=++cnt; lst=cnt; l[np]=l[p]+1;
    		for(;p && !ch[p][c];p=fa[p]) ch[p][c]=np;
    		if(!p) fa[np]=1;
    		else {
    			int q=ch[p][c];
    			if(l[q]==l[p]+1) fa[np]=q;
    			else {
    				int nq=++cnt; l[nq]=l[p]+1;
    				memcpy(ch[nq],ch[q],sizeof(ch[q]));
    				fa[nq]=fa[q]; fa[q]=fa[np]=nq;
    				for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    			}
    		}
    	}
    	inline int query1(int x){
    		int p=1,ret=0;
    		for(int i=x;i<=lena;i++) {
    			if(ch[p][A[i]-'a']) p=ch[p][A[i]-'a'],ret++;
    			else return ret+1;	
    		}
    		return 1e9;
    	}
    	inline void query3(int x,int y,int l){
    		for(int i=0;i<26;i++){
    			if(!ch[y][i] && nxta[x][i]) ans=min(ans,l);
    			else if(ch[y][i] && nxta[x][i]) query3(nxta[x][i],ch[y][i],l+1);
    		}
    	}
    }sam;
    
    inline int query2(int x){
    	int now=0,ret=0;
    	for(int i=x;i<=lena;i++){
    		if(!nxtb[now][A[i]-'a']) return ret+1;
    		ret++; now=nxtb[now][A[i]-'a'];
    	}
    	return 1e9;
    }
    
    int query4(int x,int y){
    	if(x && !y) return 1;
    	if(vis[x][y]) return vis[x][y];
    	int tmp=1e9;
    	for(int i=0;i<26;i++){
    		if(!nxta[x][i]) continue;
    		tmp=min(tmp,query4(nxta[x][i],nxtb[y][i]));
    	}
    	vis[x][y]=tmp+1;
    	return vis[x][y];
    }
    
    int main(){
    	scanf("%s%s",A+1,B+1); sam.cnt=sam.lst=1;
    	lena=strlen(A+1); lenb=strlen(B+1);
    	for(int i=lena;~i;i--) {
    		for(int j=0;j<26;j++) nxta[i][j]=prea[j];
    		prea[A[i]-'a']=i; 
    	}
    	for(int i=lenb;~i;i--){
    		for(int j=0;j<26;j++) nxtb[i][j]=preb[j];
    		preb[B[i]-'a']=i;
    	}	
    	for(int i=1;i<=lenb;i++) sam.insert(B[i]-'a');
    	for(int i=1;i<=lena;i++) ans=min(ans,sam.query1(i));
    	printf("%d
    ",(ans==1e9)?-1:ans); ans=1e9;
    	for(int i=1;i<=lena;i++) ans=min(ans,query2(i));
    	printf("%d
    ",(ans==1e9)?-1:ans); ans=1e9; sam.query3(0,1,0);
    	printf("%d
    ",(ans==1e9)?-1:ans+1); ans=query4(0,0)-1;
    	printf("%d
    ",(ans==1e9)?-1:ans);
    	return 0;
    }
    
  • 相关阅读:
    php下的jsonp使用实例
    jquery ajax jsonp跨域调用实例代码
    js/ajax跨越访问-jsonp的原理和实例(javascript和jquery实现代码)
    jsonp实现跨域访问
    jsonp调用实例
    Jsonp和java操作例子
    JSONP实例
    跨平台移动开发工具:PhoneGap与Titanium全方位比拼
    混合开发模式下主流移动开发平台分析
    企业移动信息化应用开发模式选型指南
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10290924.html
Copyright © 2020-2023  润新知