UVALive 4657 Top 10(自动机)

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2658

题意:给出n个串以及另外m个串,对于每个m串输出一行,输出n个串那些串包含的该串。输出先按照长度、再按照字典序、再按照编号。最多输出10个。

思路:现将m个串插入trie建图。然后用排序后的n个串依次插入。







const int N=1000005;





struct node

{

    int next[26],fail,flag,x;



    void init()

    {

        clr(next,0);

        fail=0;

        flag=0;

        x=-1;

    }

};



node a[N];

int e,n,m;

int mp[100005];

vector<int> V[N];







void insert(char s[],int t)

{

    int i,k,p=0;

    for(i=0;s[i];i++)

    {

        k=s[i]-'a';

        if(a[p].next[k]==0)

        {

            a[e].init();

            V[e].clear();

            a[p].next[k]=e++;

        }

        p=a[p].next[k];

    }

    a[p].flag=1;

    mp[t]=p;

}



queue<int> Q;



void build()

{

    int i,j,k,p,q;

    FOR0(i,26) if(a[0].next[i]) Q.push(a[0].next[i]);

    while(!Q.empty())

    {

        k=Q.front();

        Q.pop();

        for(i=0;i<26;i++)

        {

            if(a[k].next[i]>0)

            {

                p=a[k].next[i];

                q=a[k].fail;

                Q.push(p);

                a[p].fail=a[q].next[i];

            }

            else

            {

                q=a[k].fail;

                a[k].next[i]=a[q].next[i];

            }

        }

    }

}





string s[20005];

char str[100005];





void find(string s,int id)

{

    int i,j,k,p=0,q;

    FOR0(i,SZ(s))

    {

        k=s[i]-'a';

        while(a[p].next[k]==0&&p) p=a[p].fail;

        if(a[p].next[k]) p=a[p].next[k];

        q=p;

        while(q>0)

        {

            if(a[q].flag&&a[q].x!=id&&SZ(V[q])<10)

            {

                V[q].pb(id);

                a[q].x=id;

            }

            q=a[q].fail;

        }

    }

}





int cmp(int x,int y)

{

    int Lx=SZ(s[x]),Ly=SZ(s[y]);

    if(Lx!=Ly) return Lx<Ly;

    if(s[x]!=s[y]) return s[x]<s[y];

    return x<y;

}



int A[N];



int main()

{

    while(scanf("%d",&n)!=-1)

    {

        a[0].init();e=1; V[0].clear();

        int i,j,k;

        FOR0(i,n) RD(s[i]),A[i]=i;

        sort(A,A+n,cmp);

        RD(m);

        FOR0(i,m) RD(str),insert(str,i);

        build();

        FOR0(i,n) find(s[A[i]],A[i]);

        FOR0(i,m)

        {

            k=mp[i];

            if(SZ(V[k])==0) puts("-1");

            else

            {

                for(j=0;j<SZ(V[k])-1;j++)

                {

                    printf("%d ",V[k][j]+1);

                }

                printf("%d\n",V[k][j]+1);

            }

        }

    }

    return 0;

}

  

 

你可能感兴趣的:(live)