HDU 6138 Fleet of the Eternal Throne 多校#8 AC自动机

题意:给出n(<=1e5)个串(总长度<=1e5),以及q(<=300,数据有点弱,q改成1e5才好)次询问,每次询问给出x和y,表示输入的第x个和第y个串,要求找出一个最长的字串p,满足:p是x的字串,p是y的字串,且p是这n个串中某一个(可以是多个)的前缀,输出这个最大的长度。

参考http://blog.csdn.net/wubaizhe/article/details/77431875
果然对于ac自动机一点都不熟。居然找了那么久才找到sb错误。。。
收货:

  1. 可以把所以的字符串都放到一个长的s中,只要有pos标记就可以了。。然后+len+1来切断。。
#include<algorithm>
#include<vector>
#include<cstring>
#include<string>
#include<iomanip>
#include<cstdio>
#include<stack>
#include<iostream>
#include<map>
#include<queue>
#include<cmath>
#include<strstream>
using namespace std;
#define sf scanf
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a));
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define MP make_pair
#define N 1000150
#define M 200020
#define mod 998244353
#define ULL unsigned long long
#define LL long long
#define inf 0x3f3f3f3f
//freopen("in.txt","r",stdin);
//2017年08月21日10:35:07      15min

int pos[N];
int dep[N];
char s[N];
int id[N];
struct Trie {
    int next[N][26],fail[N<<2];
    int col[N];
    int root,L;
    int newnode() {
        for(int i = 0;i < 26;i++)
            next[L][i] = -1;
        L++;
        return L-1;
    }
    inline int ID(char s){return s-'a';}
    void init() {
        mem(col,-1);
        L = 0;
        root = newnode();
    }
    void insert(char buf[]) {
        int len = strlen(buf);
        int now = root;
        for(int i = 0;i < len;i++) {
            int id=ID(buf[i]);
            if(next[now][id] == -1){
                next[now][id] = newnode();
                dep[next[now][id]]=i+1;
            }
            now = next[now][id];
        }
    }
    void build() {
        queue<int>Q;
        fail[root] = root;
        for(int i = 0;i < 26;i++)
            if(next[root][i] == -1)
                next[root][i] = root;
            else {
                fail[next[root][i]] = root;
                Q.push(next[root][i]);
            }
        while( !Q.empty() ) {
            int now = Q.front(); Q.pop();
            for(int i = 0;i < 26;i++)
                if(next[now][i] == -1)
                    next[now][i] = next[fail[now]][i];
                else {
                    fail[next[now][i]]=next[fail[now]][i];
                    Q.push(next[now][i]);
                }
        }
    }
    int query(char *s,int x,bool sta){
        int len=strlen(s),u=root,ans=0;
        for(int i=0;i<len;++i){
            int id=ID(s[i]);
            u=next[u][id];
            int tmp=u;
            while(tmp){
                if(!sta)col[tmp]=x;
                else if(col[tmp]==x)ans=max(ans,dep[tmp]);
                tmp=fail[tmp];
            }
        }
        return ans;
    }
}ac;
int main(){
    //freopen("in.txt","r",stdin);
    int T;sf("%d",&T);
    while(T--){
        ac.init();
        int n;sf("%d",&n);
        int now=0;
        rep(i,1,n){
            pos[i]=now;
            sf("%s",s+now);
            ac.insert(s+now);
            int len=strlen(s+now);
            now+=len+1;
        }
        ac.build();
        int q;sf("%d",&q);
        while(q--){
            int x,y;sf("%d%d",&x,&y);
            ac.query(s+pos[x],q,0);
            int ans=ac.query(s+pos[y],q,1);
            pf("%d\n",ans);
        }
    }
}
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页