zoukankan      html  css  js  c++  java
  • SP1811 LCS

    (color{#0066ff}{ 题目描述 })

    输入2 个长度不大于250000的字符串,输出这2 个字符串的最长公共子串。如果没有公共子串则输出0 。

    (color{#0066ff}{输入格式})

    两个字符串

    (color{#0066ff}{输出格式})

    一个整数,为 所求答案

    (color{#0066ff}{输入样例})

    alsdfkjfjkdsal
    fdjskalajfkdsla
    

    (color{#0066ff}{输出样例})

    3
    

    (color{#0066ff}{数据范围与提示})

    none

    (color{#0066ff}{ 题解 })

    对第一个串建立后缀自动机

    用第二个串在自动机上跑匹配

    匹配一下就取max

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    LL in() {
    	char ch; int x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    const int maxn = 6e5 + 5;
    struct SAM {
    protected:
    	struct node {
    		node *ch[26], *fa;
    		int len, siz;
    		node(int len = 0, int siz = 0): fa(NULL), len(len), siz(siz) {
    			memset(ch, 0, sizeof ch);
    		}
    	};
    	node *root, *tail, *lst;
    	node pool[maxn];
    	void extend(int c) {
    		node *o = new(tail++) node(lst->len + 1, 1), *v = lst;
    		for(; v && !v->ch[c]; v = v->fa) v->ch[c] = o;
    		if(!v) o->fa = root;
    		else if(v->len + 1 == v->ch[c]->len) o->fa = v->ch[c];
    		else {
    			node *n = new(tail++) node(v->len + 1), *d = v->ch[c];
    			std::copy(d->ch, d->ch + 26, n->ch);
    			n->fa = d->fa, d->fa = o->fa = n;
    			for(; v && v->ch[c] == d; v = v->fa) v->ch[c] = n;
    		}
    		lst = o;
    	}
    	void clr() {
    		tail = pool;
    		root = lst = new(tail++) node();
    	}
    public:
    	SAM() { clr(); }
    	void ins(char *s) { for(char *p = s; *p; p++) extend(*p - 'a'); }
    	int match(char *s) {
    		int ans = 0;
    		node *o = root;
    		int len = 0;
    		for(char *p = s; *p; p++) {
    			int pos = *p - 'a';
    			if(o->ch[pos]) o = o->ch[pos], len++;
    			else {
    				while(o && !o->ch[pos]) o = o->fa;
    				if(!o) o = root, len = 0;
    				else len = o->len + 1, o = o->ch[pos];
    			}
    			ans = std::max(ans, len);
    		}
    		return ans;
    	}
    }sam;
    char s[maxn];
    int main() {
    	scanf("%s", s);
    	sam.ins(s);
    	scanf("%s", s);
    	printf("%d
    ", sam.match(s));
    	return 0;
    }
    
  • 相关阅读:
    归并排序(Merge Sort)
    AtCoder AGC035D Add and Remove (状压DP)
    AtCoder AGC034D Manhattan Max Matching (费用流)
    AtCoder AGC033F Adding Edges (图论)
    AtCoder AGC031F Walk on Graph (图论、数论)
    AtCoder AGC031E Snuke the Phantom Thief (费用流)
    AtCoder AGC029F Construction of a Tree (二分图匹配)
    AtCoder AGC029E Wandering TKHS
    AtCoder AGC039F Min Product Sum (容斥原理、组合计数、DP)
    AtCoder AGC035E Develop (DP、图论、计数)
  • 原文地址:https://www.cnblogs.com/olinr/p/10251751.html
Copyright © 2011-2022 走看看