zoukankan      html  css  js  c++  java
  • LOJ-2123 最短不公共子串 后缀自动机,子序列自动机

    LOJ-2123 最短不公共子串 后缀自动机,子序列自动机

    前几天做了一道GYM的最短非公共子串,利用子序列自动机性质DP来做,后来又发现了此题 HEOI2015

    题意

    给定小写字母串(A,B) 计算

    1.A的一个最短的子串,它不是B的子串

    2.A的一个最短的子串,它不是B的子序列

    3.A的一个最短的子序列,它不是B的子串

    4.A的一个最短的子序列,它不是B的子序列

    [len leq 2000 ]

    分析

    后缀自动机可以识别一个字符串的所有子串,子序列自动机可以识别一个字符串的所有子序列

    于是我们发现只要建立两个串的后缀自动机和子序列自动机,在上面跑一遍BFS即可

    复杂度(O(n^2))

    代码

    struct Auto{
    	int trans[maxn][26],maxlen[maxn],link[maxn],siz,last;
    	int Last[maxn];
    	int rt;
    	void clear_sam(){
    		rt = 1;
    		memset(trans,0,sizeof trans);
    		memset(link,0,sizeof link);
    		last = siz = 1;
    	}
    	void clear_seq(){
    		rt = 2015;
    		memset(trans,0,sizeof trans);
    		memset(Last,0,sizeof Last);
    	}
    	inline void extend(int id){
    		int cur = ++siz,p;
    		maxlen[cur] = maxlen[last] + 1;
    		for(p = last;p && !trans[p][id];p = link[p]) trans[p][id] = cur;
    		if(!p) link[cur] = 1;
    		else{
    			int q = trans[p][id];
    			if(maxlen[q] == maxlen[p] + 1) link[cur] = q;
    			else{
    				int clone = ++siz;
    				maxlen[clone] = maxlen[p] + 1;
    				memcpy(trans[clone],trans[q],sizeof(trans[q]));
    				link[clone] = link[q];
    				for(;p && trans[p][id] == q;p = link[p]) trans[p][id] = clone;
    				link[cur] = link[q] = clone;	
    			}
    		} 
    		last = cur;
    	}
    	void sam(char *s){
    		clear_sam();
    		int len = strlen(s + 1);
    		for(int i = 1;i <= len;i++) extend(s[i] - 'a');
    	}
    	void seq(char *s){
    		clear_seq();
    		int len = strlen(s + 1);
    		for(int i = len;i >= 1;i--){
    			for(int j = 0;j < 26;j++) trans[i][j] = Last[j];
    			Last[s[i] - 'a'] = i;
    		}
    		for(int i = 0;i < 26;i++) trans[rt][i] = Last[i];
    	}
    }a,b;
    
    struct node{
    	int a,b,dep;
    };
    
    bool vis[maxn][maxn];
    char s1[maxn],s2[maxn]; 
    
    int query(){
    	memset(vis,0,sizeof vis);
    	queue<node> q;
    	vis[a.rt][b.rt] = 1;
    	q.push({a.rt,b.rt,0});
    	while(!q.empty()) {
    		node u = q.front();
    		q.pop();
    		for(int i = 0;i < 26;i++){
    			int s = a.trans[u.a][i],t = b.trans[u.b][i];
    			if(vis[s][t]) continue;
    			if(s && !t) {
    				return u.dep + 1;
    			}
    			vis[s][t] = 1;
    			q.push({s,t,u.dep + 1});
    		}
    	}
    	return -1;
    }
    
    int main(){
    	scanf("%s%s",s1 + 1,s2 + 1);
    	a.sam(s1);
    	b.sam(s2);
    	cout << query() << '
    ';
    	a.sam(s1);
    	b.seq(s2);
    	cout << query() << '
    ';
    	a.seq(s1);
    	b.sam(s2);
    	cout << query() << '
    ';
    	a.seq(s1);
    	b.seq(s2);
    	cout << query() << '
    ';
    }
    
  • 相关阅读:
    07java基础知识
    06java基础知识
    我们都忽略了Html5的力量,如果只看成一种技术就大错特错了!
    “微信应用号对行业影响”之一,app开发速来围观
    App开发中甲乙方冲突会闹出啥后果?H5 APP 开发可以改变现状吗
    开发APP不搞清楚这20个问题,必然沦为一场灾难
    H5 App设计者需要注意的21条禁忌
    H5 APP开发必读,20个你不知道的Html5新特征和窍门
    H5 App如此强悍,要降薪的恐怕已不只是iOS程序员
    关于APP,原生和H5开发技术的争论
  • 原文地址:https://www.cnblogs.com/hznumqf/p/14649465.html
Copyright © 2011-2022 走看看