Luo Gu P2414 / LOJ2444 / BZOJ2434 [NOI2011] Ali typewriter

Since the AC automatic machine was invented in 1975, so this can be regarded as ancient typewriter Technology

First examines the nature of AC automaton we can know, fail pointer is invented is to skip all along it and jump to the current node in the Trie suffix representative of the nodes corresponding to a string, so we just inside statistics y how many nodes can skip to the end x jump fail on it.

However, this thing certainly can not jump violence. . . Fail to become difficult to see the side, then no, fail metastasis formation of a tree (the tree fail), if we put y nodes are dyed in the trees, the answer is x its sub-tree has several knot points are dyed, this may order + Fenwick tree dfs.

So the question is how fast staining all nodes to y. Consider off-line, running dfs on Trie, dyeing, when exiting each point into the recovery, then all nodes when just ran to the end of the y y is stained. Here there prior to all inquiries about y, uniform processing can be.

#include<cstdio>
#include<cctype>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int N=100050;
int f[N],ch[N][26],ch2[N][26],cnt=0,pos[N],fail[N],ans[N],dfn[N],dfl[N],dfsc=0,c[N],G[N],to[N],nxt[N],sz=0;
char s[N];
vector<int> qry[N],qp[N];
queue<int> Q;
inline void bfs(){
    int i,u;
    for(i=0;i<26;++i)if(ch[0][i])Q.push(ch[0][i]);
    while(!Q.empty()){
        u=Q.front();Q.pop();
        for(i=0;i<26;++i)if(ch[u][i]){
            fail[ch[u][i]]=ch[fail[u]][i];
            Q.push(ch[u][i]);
        }else ch[u][i]=ch[fail[u]][i];
    }
}
inline void adde(int u,int v){
    to[++sz]=v;nxt[sz]=G[u];G[u]=sz;
}
inline void add(int x,short k){
    for(;x<=cnt+1;x+=x&-x)c[x]+=k;
}
inline int sum(int x){
    int s=0;
    for(;x;x^=x&-x)s+=c[x];
    return s;
}
void dfs1(int u){
    dfn[u]=++dfsc;
    for(int i=G[u];i;i=nxt[i])dfs1(to[i]);
    dfl[u]=dfsc;
}
void dfs2(int u){
    int i;
    add(dfn[u],1);
    for(i=0;i<qry[u].size();++i)ans[qp[u][i]]=sum(dfl[qry[u][i]])-sum(dfn[qry[u][i]]-1);
    for(i=0;i<26;++i)if(ch2[u][i])dfs2(ch2[u][i]);
    add(dfn[u],-1);
}
int main(){
    int q,i,x,y,l,n=0,k=0;
    scanf("%s",s);l=strlen(s);
    for(i=0;i<l;++i)if(islower(s[i])){
        if(!ch[k][s[i]-'a'])ch[k][s[i]-'a']=++cnt;
        f[ch[k][s[i]-'a']]=k;k=ch[k][s[i]-'a'];
    }else if(s[i]=='B')k=f[k];
    else pos[++n]=k;
    memcpy(ch2,ch,sizeof(ch2));
    bfs();
    for(i=1;i<=cnt;++i)adde(fail[i],i);
    dfs1(0);
    scanf("%d",&q);
    for(i=0;i<q;++i){
        scanf("%d%d",&x,&y);
        qry[pos[y]].push_back(pos[x]);qp[pos[y]].push_back(i);
    }
    dfs2(0);
    for(i=0;i<q;++i)printf("%d\n",ans[i]);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/sunshine-chen/p/11315767.html