记录编号 170692 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [POI 2000] 最长公共子串 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.057 s
提交时间 2015-07-15 07:39:24 内存使用 0.41 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<bitset>
using namespace std;
#define Nil NULL//Orz 光神!
const int SIZE=20010;
class Suffix_Automaton{
public:
	class Node{
	public:
		int len;
		Node *suflink;
		Node *ch[31];
		bitset<31> reach;
		Node(){
			len=0;
			suflink=Nil;
			memset(ch,0,sizeof(ch));
		}
	};
	Node *root,*last;
	int n;
	Node* lis[SIZE];
	int findpos(Node *a){
		if(!a) return -1;
		for(int i=0;i<n;i++){
			if(lis[i]==a) return i;
		}
		return -2;
	}
	void print(Node *a){
		cout<<"地址:"<<findpos(a)<<endl;
		cout<<"len:"<<a->len<<endl;
		cout<<"suflink:"<<findpos(a->suflink)<<endl;
		for(int i=0;i<31;i++){
			if(a->ch[i]!=Nil){
				cout<<(char)('a'+i)<<" :"<<findpos(a->ch[i])<<endl;
			}
		}
		cout<<"reach list:";for(int i=0;i<31;i++){if(a->reach[i]){cout<<(char)('a'+i);}}cout<<endl;
		cout<<endl;
	}
	void clear(void){
		root=new Node();
		last=root;
		lis[0]=root;
		n=1;
	}
	Suffix_Automaton(void){clear();}
	void Insert(char c){
		int k=c-'a';
		Node *cur=new Node();
		lis[n++]=cur;
		cur->len=last->len+1;
		Node *p=last;
		while(p!=Nil&&p->ch[k]==Nil){
			p->ch[k]=cur;
			p=p->suflink;
		}
		if(p==Nil) cur->suflink=root;
		else{
			Node *q=p->ch[k];
			if(q->len==p->len+1) cur->suflink=q;
			else{
				Node *clone=new Node();
				lis[n++]=clone;
				*clone=*q;
				clone->len=p->len+1;
				cur->suflink=clone;
				q->suflink=clone;
				while(p!=Nil&&p->ch[k]==q){
					p->ch[k]=clone;
					p=p->suflink;
				}
			}
		}
		last=cur;
	}
	class cmp{//排个序真麻烦......
	public:
		bool operator () (Node *a,Node *b){
			return a->len<b->len;
		}
	};
	int calc_LCS(int dnum){
		int ans=0;
		sort(lis,lis+n,cmp());
		for(int i=n-1;i>=0;i--){
			Node *p=lis[i];
			if(p->suflink!=Nil) p->suflink->reach|=p->reach;
			for(int k=0;k<26;k++)
				if(p->ch[k]!=Nil)
					p->reach|=p->ch[k]->reach;
			for(int k=26;k<31;k++)
				if(p->ch[k]!=Nil)
					p->reach[k]=true;
			bool flag=true;
			for(int k=26;k<26+dnum;k++)
				if(!p->reach[k]) flag=false;
			if(flag) ans=max(ans,p->len);
		}
		return ans;
	}
}M;
int N;
char str[SIZE]={0};
int main(){
	freopen("pow.in","r",stdin);
	freopen("pow.out","w",stdout);
	scanf("%d",&N);
	for(int i=1;i<=N;i++){
		scanf("%s",str);
		int L=strlen(str);
		str[L]='z'+i;
		for(int i=0;i<=L;i++)
			M.Insert(str[i]);
	}
	printf("%d\n",M.calc_LCS(N));
	return 0;
}