BZOJ 2434 阿狸的打字机

Posted on 2017-02-07 22:14  ziliuziliu  阅读(130)  评论(0编辑  收藏  举报

题解网上都有。。。要注意下细节。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxn 100500
#define maxv 100500
#define maxe 200500
using namespace std;
int ls,m,x,y,son[maxn][27],root,tot=0,cnt=0,t[maxn],fail[maxn],ans[maxn];
int l[maxv],r[maxv],pos[maxn],n=0,fath[maxv],g[maxv],nume=1,p=1;
queue <int> qs;
struct query
{
    int x,y,id;
    query (int x,int y,int id):x(x),y(y),id(id) {}
    query () {}
}q[maxn];
struct edge
{
    int v,nxt;
}e[maxe];
char s[maxn];
bool cmp(query x,query y) {return x.y<y.y;}
int lowbit(int x) {return (x&(-x));}
void addedge(int u,int v)
{
    e[++nume].v=v;
    e[nume].nxt=g[u];
    g[u]=nume;
}
void insert_AC()
{
    int now=root;
    for (int i=0;i<ls;i++)
    {
        if (s[i]=='B') now=fath[now];
        else if (s[i]=='P') pos[++n]=now;
        else
        {
            int nb=s[i]-'a'+1;
            if (!son[now][nb]) {son[now][nb]=++tot;fath[tot]=now;}
            now=son[now][nb];
        }
    }
}
void build_AC()
{
    qs.push(root);
    while (!qs.empty())
    {
        int head=qs.front();qs.pop();
        for (int i=1;i<=26;i++)
        {
            if (!son[head][i]) son[head][i]=son[fail[head]][i];
            else
            {
                if (!head) fail[son[head][i]]=root;
                else fail[son[head][i]]=son[fail[head]][i];
                qs.push(son[head][i]);
            }
        }
    }
    for (int i=1;i<=tot;i++) 
    {
        addedge(fail[i],i);
        addedge(i,fail[i]);
    }
}
void dfs(int now,int fath)
{
    l[now]=r[now]=++cnt;
    for (int i=g[now];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (v==fath) continue;
        dfs(v,now);r[now]=max(r[now],r[v]);
    }
}
void add_query()
{    
    scanf("%d",&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        q[i]=query(x,y,i);
    }
    sort(q+1,q+m+1,cmp);
}
void add(int x,int val)
{
    for (int i=x;i<=cnt;i+=lowbit(i))
        t[i]+=val;
}
int ask(int x)
{
    int ret=0;
    for (int i=x;i>=1;i-=lowbit(i))
        ret+=t[i];
    return ret;
}
void ask_()
{
    int now=root,kr=0;
    for (int i=0;i<ls;i++)
    {
        if (s[i]=='B') {add(l[now],-1);now=fath[now];}
        else if (s[i]=='P')
        {
            kr++;
            for (;p<=m;p++)
            {
                if (q[p].y!=kr) break;
                ans[q[p].id]=ask(r[pos[q[p].x]])-ask(l[pos[q[p].x]]-1);
            }
        }
        else
        {
            now=son[now][s[i]-'a'+1];
            add(l[now],1);
        }
    }
}
int main()
{
    n=root=tot=0;
    scanf("%s",s);ls=strlen(s);
    insert_AC();build_AC();    
    dfs(root,root);add_query();
    ask_();
    for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
    return 0;
}