# 【bzoj2434】: [Noi2011]阿狸的打字机 字符串-AC自动机-BIT

【bzoj2434】: [Noi2011]阿狸的打字机

x串在y串上的匹配次数就是y在自动机所有节点上能够通过fail走到x最后一个节点的个数

（就是y串任意一个前缀的后缀能匹配到x的个数）【bzoj3172】: [Tjoi2013]单词差不多

  1 /* http://www.cnblogs.com/karl07/ */
2 #include <cstdlib>
3 #include <cstdio>
4 #include <cstring>
5 #include <cmath>
6 #include <algorithm>
7 using namespace std;
8 const int N=1e5+5;
9 char s[N];
10 struct edge{ int next,to; edge(int next=0,int to=0) : next(next),to(to){}; }e[N];
11 struct trie{ int th; trie *next[26],*fail,*fa; }t[N],*NEW=t,*root=t,*q[N],*now=t,*sth[N];
12 struct Query{int x,y,id;}Q[N];
14 int first[N],st[N],ed[N],BIT[N*2],ans[N];
15 #define pn p->next[i]
16 #define pnf p->next[i]->fail
17 #define lowbit(x) (x&-x)
18
19 void modify(int x,int m){
20     for (;x<=N;x+=lowbit(x)) BIT[x]+=m;
21 }
22
23 int query(int l,int r){
24     int a1=0,a2=0;
25     for (;r;r-=lowbit(r)) a1+=BIT[r];
26     for (l--;l;l-=lowbit(l)) a2+=BIT[l];
27     return a1-a2;
28 }
29
32 }
33
34 trie *new1(trie *p){ NEW++; NEW->fa=p; return NEW; }
35
36 trie *insert(trie *p,int i,int x){
37     if (!pn) pn=new1(p);
38     if (x!=0) modify(st[pn->th],1);
39     return pn;
40 }
41
42 trie *remove(trie *p,int x){
43     if (x!=0) modify(st[p->th],-1);
44     return p->fa;
45 }
46
47 void build_fail(){
48     trie *p=q[1]=root;
49     root->th=1;
50     for (int i=0;i<26;i++) if (pn) q[++r]=pn,pnf=root,pn->th=r,addedge(1,pn->th);
51     while (l<r){
52         p=q[++l];
53         for (int i=0;i<26;i++){
54             if (pn){
55                 q[++r]=pn,pn->th=r;
56                 for (pnf=p->fail ; pnf!=root && !pnf->next[i] ; pnf=pnf->fail);
57                 if (pnf->next[i]) pnf=pnf->next[i];
59             }
60         }
61     }
62 }
63
64 void dfs(int p){
65     st[p]=++df;
66     for (int x=first[p];x;x=e[x].next){
67         if (e[x].to) dfs(e[x].to);
68     }
69     ed[p]=df;
70 }
71
72 bool oper(Query a, Query b){return a.y<b.y;}
73
74 int main(){
75     scanf("%s",s);
76     scanf("%d",&n);
77     for (int i=1;i<=n;i++) {
78         scanf("%d%d",&Q[i].x,&Q[i].y);
79         Q[i].id=i;
80     }
81     sort(Q+1,Q+1+n,oper);
82     for (int l=strlen(s),i=0;i<l;i++){
83         if (s[i]>='a' && s[i]<='z') now=insert(now,s[i]-'a',0);
84         if (s[i]=='B') now=remove(now,0);
85         if (s[i]=='P') sth[++c2]=now;
86     }
87     build_fail();
88     dfs(1);
89     now=root;
90     for (int i=1,j=0;i<=n;i++){
91         while (sth[Q[i].y]!=now) {
92             if (s[j]>='a' && s[j]<='z') now=insert(now,s[j]-'a',1);
93             if (s[j]=='B') now=remove(now,1);
94             j++;
95         }
96         ans[Q[i].id]=query(st[sth[Q[i].x]->th],ed[sth[Q[i].x]->th]);
97     }
98     for (int i=1;i<=n;i++) printf("%d\n",ans[i]);
99     return 0;
100 }
View Code

posted @ 2017-04-01 20:25  karl07  阅读(187)  评论(0编辑  收藏  举报