[AC automaton] [Fenwick tree] luogu P2414 Ali typewriter

https://www.luogu.org/problem/P2414

 

analysis

A number of easy to find the query string part of the string B is asked how many times the access string B, dance through each point in the chain fail to reach the end of the string of A

Can be found if the fail tree built out, each equivalent to a point is reached, which go out into the tree fail weights +1, -1 leaving, when it reaches the end of the sequence B, A query string at the end of the tree of subtrees fail weights and

Fenwick tree with DFS order and can be easily resolved

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define lowbit(x) x&-x
using namespace std;
const int N=2e5+10;
struct Graph {
    int v,nx;
}g[N];
int gcnt,list[N];
int fail[N],t[N][26],cnt,v[N];
struct Query {
    int x,y,id;
}q[N];
int m,len,tme,p;
int l[N],r[N],end[N],ans[N],f[N];
char c[N];

void Add(int u,int v) {
    g[++gcnt]=(Graph){v,list[u]};list[u]=gcnt;
}

bool CMP(Query a,Query b) {
    return a.y<b.y;
}

void Insert() {
    int x=0,id=0;
    for (int i=1,n=strlen(c+1);i<=n;i++) {
        if (c[i]=='B') {
            x=f[x];
            continue;
        }
        if (c[i]=='P') {
            end[++id]=x;
            continue;
        }
        if (!t[x][c[i]-'a']) f[t[x][c[i]-'a']=++cnt]=x;
        x=t[x][c[i]-'a'];
    }
}

void Build() {
    queue<int> q;
    while (!q.empty()) q.pop();
    for (int i=0;i<26;i++) if (t[0][i]) q.push(t[0][i]),Add(0,t[0][i]);
    while (!q.empty()) {
        int u=q.front();q.pop();
        for (int i=0;i<26;i++)
            if (t[u][i]) {
                int now=fail[u];
                while (now&&!t[now][i]) now=fail[now];
                fail[t[u][i]]=t[now][i];Add(t[now][i],t[u][i]);
                q.push(t[u][i]);
            }
    }
}

void DFS(int u) {
    l[u]=++tme;
    for (int i=list[u];i;i=g[i].nx) DFS(g[i].v);
    r[u]=tme;
}

void Addc(int x,int c) {
    for (;x<=tme;x+=lowbit(x)) v[x]+=c;
}

int Sum(int x) {
    int ans=0;
    for (;x;x-=lowbit(x))ans+=v[x];
    return ans;
}

void Trie() {
    int x=0;
    for (int i=1,n=strlen(c+1);i<=n;i++) {
        if (c[i]=='B') {
            Addc(l[x],-1);x=f[x];
            continue;
        }
        if (c[i]=='P') {
            while (end[q[p].y]==x) ans[q[p].id]=Sum(r[end[q[p].x]])-Sum(l[end[q[p].x]]-1),p++;
            continue;
        }
        x=t[x][c[i]-'a'];Addc(l[x],1);
    }
}

int main() {
    scanf("%s",c+1);
    Insert();
    scanf("%d",&m);
    for (int i=1;i<=m;i++) scanf("%d%d",&q[i].x,&q[i].y),q[i].id=i;
    sort(q+1,q+m+1,CMP);
    Build();
    DFS(0);
    p=1;len=0;Trie();
    for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
}
View Code

 

Guess you like

Origin www.cnblogs.com/mastervan/p/11324875.html