zoukankan      html  css  js  c++  java
  • 【题解】SP10570 【LONGCS

    (color{Red}{Link})

    ( ext{Solution:})

    还是( ext{Suffix Tree.})

    根据(color{Blue}{Link})我们可以得到一个普适性较强的做法。

    而这题就是多组数据。改下数据即可。

    但是字符串的输入要绝对注意,每一次的清空都不能落下。

    #include<bits/stdc++.h>
    #include<ctime>
    using namespace std;
    const int MAXN=2e6+10;
    char Z[20][100001];
    int n,val[MAXN],ans,M,num,Case;
    int sum[20][MAXN];
    const int inf=(1<<30);
    struct SuffixTree {
    	int link[MAXN],ch[MAXN][50],now,rem,n;
    	int start[MAXN],len[MAXN],tail,s[MAXN];
    	SuffixTree() {
    		tail=now=1;
    		rem=n=0;
    		len[0]=inf;
    	}
    	inline int build(int a,int b) {
    		link[++tail]=1;
    		start[tail]=a;
    		len[tail]=b;
    		return tail;
    	}
    	void Extend(int x) {
    		s[++n]=x;
    		++rem;
    		for(int last=1; rem;) {
    			while(rem>len[ch[now][s[n-rem+1]]])
    				rem-=len[now=ch[now][s[n-rem+1]]];
    			int &v=ch[now][s[n-rem+1]];
    			int c=s[start[v]+rem-1];
    			if(!v||x==c) {
    				link[last]=now;
    				last=now;
    				if(!v)v=build(n,inf);
    				else break;
    			} else {
    				int u=build(start[v],rem-1);
    				ch[u][c]=v;
    				ch[u][x]=build(n,inf);
    				start[v]+=rem-1;
    				len[v]-=rem-1;
    				link[last]=v=u;
    				last=u;
    			}
    			if(now==1)--rem;
    			else now=link[now];
    		}
    	}
    	void clear(){
    		memset(start,0,sizeof(start));
    		memset(len,0,sizeof(len));
    		memset(ch,0,sizeof(ch));
    		memset(link,0,sizeof(link));
    		memset(s,0,sizeof(s));
    		tail=now=1;rem=n=0;len[0]=inf;
    	}
    } T;
    void predfs(int u,int dep) {
    	if(dep>=inf) {
    		int L=T.start[u];
    		int R=L+T.len[u]-1;
    		R=min(R,T.n);
    		for(int i=1; i<=num; ++i) {
    			if(sum[i][R]-sum[i][L-1]) {
    				val[u]|=(1<<i);
    				break;
    			}
    		}
    		return;
    	}
    	for(int i=0; i<=25+num; ++i) {
    		if(T.ch[u][i]) {
    			predfs(T.ch[u][i],dep+T.len[T.ch[u][i]]);
    			val[u]|=val[T.ch[u][i]];
    		}
    	}
    	if(val[u]==M)ans=max(ans,dep);
    }
    inline void print(char* x){
    	for(int i=1;i<=strlen(x+1);++i)cout<<x[i];
    	cout<<endl;
    }
    int main() {
    	scanf("%d",&Case);
    	//cout<<M<<endl;
    	while(Case--) {
    		scanf("%d",&num);ans=0;M=0;
    		for(int i=1;i<=num;++i)scanf("%s",Z[i]+1);
    		int G='0';
    		int len=strlen(Z[1]+1);
    		Z[1][++len]=(char)G;
    		for(int i=2; i<=num; ++i) {
    			G++;
    			int L=strlen(Z[i]+1);
    			for(int j=1; j<=L; ++j)Z[1][++len]=Z[i][j];
    			Z[1][++len]=(char)G;
    		}
    		for(int i=1; i<=num; ++i)M+=(1<<i);
    		for(int i=1; i<=len; ++i) {
    			if(Z[1][i]>='a')T.Extend(Z[1][i]-'a');
    			else T.Extend(Z[1][i]-'0'+1+25);
    		}
    		for(int i=1; i<=len; ++i) {
    			for(int j=1; j<=num; ++j)sum[j][i]=sum[j][i-1];
    			if(T.s[i]>25) {
    				int V=T.s[i]-25;
    				sum[V][i]++;
    			}
    		}
    		predfs(1,0);
    		cout<<ans<<endl;
    		T.clear();
    		memset(val,0,sizeof(val));
    		memset(sum,0,sizeof(sum));
    		//print(Z[1]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    文件载入功能
    代码调试功能
    实用项
    连贯操作
    AR模式
    表名操作
    字段映射
    ThinkPHP中的模型二
    创建数据对象
    HDU 4888 Redraw Beautiful Drawings(最大流+判最大流网络是否唯一)
  • 原文地址:https://www.cnblogs.com/h-lka/p/13194882.html
Copyright © 2011-2022 走看看