• SPOJ LCS 后缀自动机


    用后缀自动机求两个长串的最长公共子串,效果拔群。多样例的时候memset要去掉。

    解题思路就是跟CLJ的一模一样啦。

    #pragma warning(disable:4996)
    #include<cstring>
    #include<string>
    #include<iostream>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    #define maxn 250050
    using namespace std;
    
    struct State{
    	State *suf, *go[26];
    	int val;
    	State() :suf(0), val(0){
    		memset(go, 0, sizeof(go));
    	}
    }*root, *last;
    
    State statePool[maxn * 2], *cur;
    
    void init()
    {
    	cur = statePool;
    	root = last = cur++;
    }
    
    void extend(int w)
    {
    	State *p = last, *np = cur++;
    	np->val = p->val + 1;
    	while (p&&!p->go[w]) p->go[w] = np, p = p->suf;
    	if (!p) np->suf = root;
    	else{
    		State *q = p->go[w];
    		if (p->val + 1 == q->val){
    			np->suf = q;
    		}
    		else{
    			State *nq = cur++;
    			memcpy(nq->go, q->go, sizeof q->go);
    			nq->val = p->val + 1;
    			nq->suf = q->suf;
    			q->suf = nq;
    			np->suf = nq;
    			while (p&&p->go[w] == q){
    				p->go[w] = nq, p = p->suf;
    			}
    		}
    	}
    	last = np;
    }
    
    char stra[maxn], strb[maxn];
    
    int main()
    {
    	while (~scanf("%s%s", stra, strb))
    	{
    		init();
    		//memset(statePool, 0, sizeof(statePool));
    		int lena = strlen(stra);
    		for (int i = 0; i < lena; i++){
    			extend(stra[i] - 'a');
    		}
    		int ans = 0;
    		int lenb = strlen(strb);
    		State *p = root;
    		int len = 0;
    		for (int i = 0; i < lenb; i++){
    			if (p->go[strb[i] - 'a']){
    				len++; ans = max(ans, len);
    				p = p->go[strb[i] - 'a'];
    			}
    			else{
    				while (p&&!p->go[strb[i] - 'a']){
    					p = p->suf;
    				}
    				if (!p) {
    					p = root;
    					len = 0;
    				}
    				else{
    					len = p->val + 1;
    					ans = max(len, ans);
    					p = p->go[strb[i] - 'a'];
    				}
    			}
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    RPI学习--环境搭建_更新firmware
    RPI学习--环境搭建_刷卡+wiringPi库安装
    [转]VS2005 Debug时提示"没有找到MSVCR80D.dll"的解决办法
    [转]结构体字节对齐
    [转]C++运算优先级列表
    putty基本操作
    Go 修改字符串中的字符(中文乱码)
    Go part 5 结构体,方法与接收器
    pickle 和 base64 模块的使用
    原来还有 卡夫卡 这个人存在
  • 原文地址:https://www.cnblogs.com/chanme/p/3551560.html
Copyright © 2020-2023  润新知