HDU 6138 Fleet of the Eternal Throne(2017 Multi-University Training Contest 8)

来源:互联网 发布:java多线程static变量 编辑:程序博客网 时间:2024/05/23 19:09

题目链接:Fleet of the Eternal Throne
题意:给出n个字符串,m次询问,每一次询问一个(x,y),问第x和第y个字符串的最长公共部分使得这个部分是某一个字符串的前缀。
题解:注意到如果两个字符串同时匹配到了某一个前缀,那么这个前缀的长度就可以用来更新答案,所以我们可以直接根据前缀建立AC自动机,然后对于每次询问在AC自动机上匹配,用set判断是否被匹配过即可。

#include <bits/stdc++.h>using namespace std;const int N = 100100;struct Aho{    int nxt[26],fail,info,len;    void init(){        fill(nxt,nxt+26,0);        fail=info=0;    }}a[N];int id,q[N],pre;void Ist(const string& s){    int now=0,len=s.size();    for(int i=0;i<len;i++){        int t=s[i]-'a';        if(a[now].nxt[t])            now=a[now].nxt[t];        else{            a[++id].init();            a[now].nxt[t]=id;            now=id;        }        a[now].info=++pre;        a[now].len=i+1;    }}void Build(){    int now,t,head=0,tail=0;    q[tail++]=0;    a[0].fail=0;    while(head!=tail){        now=q[head++];        for(int i=0;i<26;i++)            if(a[now].nxt[i]){                for(t=a[now].fail;t&&!a[t].nxt[i];t=a[t].fail);                if(now)                    a[a[now].nxt[i]].fail=a[t].nxt[i];                q[tail++]=a[now].nxt[i];            }    }}int ans;set<int>f;string s;vector<string>v;void Match(int x,bool op){    int len=v[x].size(),now=0,t,k;    for(int i=0;i<len;i++){        t=v[x][i]-'a';        for(;now&&!a[now].nxt[t];now=a[now].fail);        now=a[now].nxt[t];        for(k=now;k;k=a[k].fail)            if(a[k].info){                if(op)                    f.insert(a[k].info);                else{                    if(f.find(a[k].info)!=f.end())                        ans=max(ans,a[k].len);                }            }    }}int main(){    ios::sync_with_stdio(false);    int T,n,m,x,y;    cin>>T;    while(T--){        v.clear();        id=pre=0;        a[0].init();        cin>>n;        for(int i=0;i<n;i++){            cin>>s;            v.push_back(s);            Ist(s);        }        Build();        cin>>m;        while(m--){            cin>>x>>y;            x--,y--;            ans=0;            f.clear();            Match(x,true);            Match(y,false);            printf("%d\n",ans);        }    }    return 0;}
阅读全文
1 0