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() << '
    ';
    }
    
  • 相关阅读:
    再谈TextField
    IOS-TextField知多少
    leftBarButtonItems
    LeftBarButtonItems,定制导航栏返回按钮
    Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法 Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法
    Unrecognized Selector Sent to Instance问题之诱敌深入关门打狗解决办法
    UNRECOGNIZED SELECTOR SENT TO INSTANCE 问题快速定位的方法
    Present ViewController,模态详解
    UILABEL AUTOLAYOUT自动换行 版本区别
    iOS自动布局解决警告Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
  • 原文地址:https://www.cnblogs.com/hznumqf/p/14649465.html
Copyright © 2011-2022 走看看