hdu 6138 - AC自动机

题目链接:点击打开链接

 

题解思路:先建立一个字典树,然后记住每个节点的深度,在求出每个节点的失败指针,将x的自身节点和x所以节点的所以失败指针都标记,再用y去搜索是否他自己的节点和自己节点的所以失败指针是否被标记过,如果是那么这点可以被考虑是否是在长的值。

 

代码:

 

#include  
#include  
#include  
#include  
#include  
#include
using namespace std;  
typedef long long ll;  
const int mx = 1e5+10;  
int n,m,root,tot;  
int nxt[mx][26],fail[mx],val[mx];  
int init(){  
    memset(nxt[tot],-1,sizeof(nxt[tot]));  
    return tot++;  
}   
bool vis[mx];
string str[mx];
void insert(int x){  
    int len  = str[x].size(),now = root;  
    for(int i = 0;i < len ;i++){  
        int id = str[x][i]-'a';  
        if(nxt[now][id]==-1) nxt[now][id] = init();  
        now = nxt[now][id]; 
        val[now] = i + 1;
    }  
}  
void bulid(){  
    queue  skt;  
    for(int i=0;i<26;i++){  
        if(nxt[root][i]==-1) nxt[root][i] = root;  
        else{  
            fail[nxt[root][i]] = root;  
            skt.push(nxt[root][i]);  
        }  
    }  
    while(!skt.empty()){  
        int now = skt.front();  
        skt.pop();   
        for(int i=0;i<26;i++){  
            if(nxt[now][i]==-1) nxt[now][i] = nxt[fail[now]][i];  
            else{  
                fail[nxt[now][i]] = nxt[fail[now]][i];  
                skt.push(nxt[now][i]);  
            }  
        }  
    }  
}
void marked(int x,int v){
    int len = str[x].size(),p = root;
    for(int i=0;i>str[i];
            insert(i);  
        }  
        bulid(); 
        scanf("%d",&m);
        while(m--){
            int x,y,ans = 0;
            scanf("%d%d",&x,&y);
            marked(x,1);
            int len = str[y].size(), p = root;
            for(int i=0;i

 

 

 

 

 

你可能感兴趣的:(字符串)