ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

poj3294

2019-05-03 09:51:43  阅读:281  来源: 互联网

标签:pre include poj3294 slink maxlen int trans


这题二分加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;
}

 

标签:pre,include,poj3294,slink,maxlen,int,trans
来源: https://www.cnblogs.com/gaudar/p/10804379.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有