• bzoj2946: [Poi2000]公共串


    SAM处女题qwq

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    #define N 4096
    
    using namespace std;
    
    struct SAM{
    	int last,size;
    	struct SAMnode{
    		int par,mx,go[26];
    		SAMnode(){}
    		SAMnode(int _mx):par(0),mx(_mx){
    			memset(go,0,sizeof(go));
    		}
    	} t[N];
    	int newnode(int _mx){t[++size]=SAMnode(_mx);return size;}
    	void clear(){size=0;last=newnode(0);}
    	void extend(char c){
    		c-='a';
    		int p=last,np=newnode(t[p].mx+1);
    		for (;p&&!t[p].go[c];p=t[p].par) t[p].go[c]=np;
    		if (!p) t[np].par=1;
    		else{
    			int q=t[p].go[c];
    			if (t[p].mx+1==t[q].mx) t[np].par=q;
    			else{
    				int nq=newnode(t[p].mx+1);
    				memcpy(t[nq].go,t[q].go,sizeof(t[q].go));
    				t[nq].par=t[q].par;
    				t[q].par=t[np].par=nq;
    				for (;p&&t[p].go[c]==q;p=t[p].par) t[p].go[c]=nq;
    			}
    		}
    		last=np;
    	}
    	int v[N],q[N];
    	int ans[N],now[N];
    	void precompute(){
    		memset(v,0,sizeof(v));
    		for (int i=1;i<=size;++i) ++v[t[i].mx];
    		for (int i=1;i<=size;++i) v[i]+=v[i-1];
    		for (int i=1;i<=size;++i) q[v[t[i].mx]--]=i;
    		
    		for (int i=1;i<=size;++i) ans[i]=t[i].mx;
    	}
    	void solve(char *s){
    		memset(now,0,sizeof(now));
    		int u=1,nowlen=0;
    		for (int i=0;s[i];++i){
    			while (u&&!t[u].go[s[i]-'a']) u=t[u].par;
    			if (!u) nowlen=0,u=1;
    			else{
    				nowlen=min(nowlen,t[u].mx)+1;
    				u=t[u].go[s[i]-'a'];
    			}
    			now[u]=max(now[u],nowlen);
    		}
    		for (int i=size;i;--i) now[t[q[i]].par]=max(now[t[q[i]].par],now[q[i]]);
    		for (int i=1;i<=size;++i) ans[i]=min(ans[i],now[i]);
    	}
    	int getans(){
    		int ret=0;
    		for (int i=1;i<=size;++i) ret=max(ret,ans[i]);
    		return ret;
    	}
    } sam;
    
    int n;
    char st[N];
    int main(){
    	scanf("%d%s",&n,st);
    	sam.clear();
    	for (int i=0;st[i];++i) sam.extend(st[i]);
    	sam.precompute();
    	for (int i=1;i<n;++i){
    		scanf("%s",st);
    		sam.solve(st);
    	}
    	printf("%d
    ",sam.getans());
    	return 0;
    }
    

      

  • 相关阅读:
    23. 霍纳法则(多项式求值快速算法)
    22. 欧几里德算法(求最大公约数GCD)
    [poj 2106] Boolean Expressions 递归
    [poj 1185] 炮兵阵地 状压dp 位运算
    [MOOC程序设计与算法二] 递归二
    [poj 3254] Corn Fields 状压dp
    [hdu 1074] Doing Homework 状压dp
    [hdu 1568] Fibonacci数列前4位
    [haut] 1281: 邪能炸弹 dp
    [hdu 2604] Queuing 递推 矩阵快速幂
  • 原文地址:https://www.cnblogs.com/wangyurzee7/p/5323284.html
Copyright © 2020-2023  润新知