poj3294
Posted gaudar
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj3294相关的知识,希望对你有一定的参考价值。
这题二分加HASH 6-7秒,如果能用unordered_map,5秒。后缀自动机200-400ms。后缀数组(没写)大概2000ms。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> #include <stack> #include <bitset> //#include <unordered_set> #define mkp make_pair #define err cout<<"here"<<endl using namespace std; const double EPS=1e-12; typedef long long lon; typedef unsigned long long ull; typedef map<ull,int>::iterator IT; const lon SZ=500010,SSZ=120,APB=26,mod=97,one=1; const lon INF=0x7FFFFFFF; int n,maxlen[SZ],minlen[SZ],trans[SZ][APB],slink[SZ]; int cnt,in[SZ]; bitset<120> bt[SZ]; struct nd{ int to,wt; nd(int a=0,int b=0):to(a),wt(b){} }; char ch[SSZ][1010]; int add(int pre,int cur,int num) { if(trans[pre][cur]) { int x=trans[pre][cur]; if(maxlen[x]==maxlen[pre]+1) { bt[x].set(num); return x; } else { int z=++cnt; memcpy(trans[z],trans[x],sizeof(trans[x])); maxlen[z]=maxlen[pre]+1; slink[z]=slink[x]; slink[x]=z; minlen[z]=maxlen[slink[z]]+1; minlen[x]=maxlen[z]+1; for(int u=pre;u!=-1&&trans[u][cur]==x;u=slink[u]) trans[u][cur]=z; bt[z].set(num); return z; } } int z=++cnt; bt[z].set(num); int u=pre; for(;u!=-1&&!trans[u][cur];u=slink[u]) { trans[u][cur]=z; } if(u==-1) { maxlen[z]=maxlen[pre]+1; minlen[z]=1; slink[z]=0; } else { int x=trans[u][cur]; if(maxlen[x]==maxlen[u]+1) { maxlen[z]=maxlen[pre]+1; minlen[z]=maxlen[x]+1; slink[z]=x; } else { int y=++cnt; memcpy(trans[y],trans[x],sizeof(trans[x])); bt[y]=bt[x]|bt[z]; maxlen[y]=maxlen[u]+1; minlen[y]=maxlen[slink[x]]+1; slink[y]=slink[x]; maxlen[x]=maxlen[x]; minlen[x]=maxlen[y]+1; slink[x]=y; maxlen[z]=maxlen[pre]+1; minlen[z]=maxlen[y]+1; slink[z]=y; for(;u!=-1&&trans[u][cur]==x;u=slink[u]) { trans[u][cur]=y; } } } return z; } void topo() { for(int i=1;i<=cnt;++i) { ++in[slink[i]]; } queue<int> q; for(int i=1;i<=cnt;++i) { if(in[i]==0) { q.push(i); } } for(;q.size();) { int fr=q.front(); q.pop(); bt[slink[fr]]|=bt[fr]; --in[slink[fr]]; if(in[slink[fr]]==0&&slink[fr]) { q.push(slink[fr]); } } } void init() { slink[0]=-1; for(int i=1;i<=n;++i) { cin>>ch[i]+1; int pre=0; for(int j=1;ch[i][j];++j) { pre=add(pre,ch[i][j]-‘a‘,i); } } topo(); } void dfs(int x,int d,int maxv) { if(d==maxv) { if(bt[x].count()<=n/2)return; ch[0][d]=0; cout<<ch[0]<<endl; return; } for(int i=0;i<APB;++i) { int t=trans[x][i]; if(t&&maxlen[t]==maxlen[x]+1) { ch[0][d]=‘a‘+i; dfs(t,d+1,maxv); } } } void work() { int maxv=0; for(int i=0;i<=cnt;++i) { if(bt[i].count()>n/2) { maxv=max(maxv,maxlen[i]); } } if(maxv==0)cout<<"?"<<endl; else { dfs(0,0,maxv); } } void release() { for(int i=0;i<=cnt;++i) { memset(trans[i],0,sizeof(trans[i])); in[i]=0; bt[i].reset(); } cnt=0; } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); int casenum; //cin>>casenum; //cout<<casenum<<endl; //for(int time=1;time<=casenum;++time) for(int time=1;cin>>n,n;++time) { if(time!=1)cout<<endl; init(); work();//err; release(); } return 0; }
以上是关于poj3294的主要内容,如果未能解决你的问题,请参考以下文章