【BZOJ】【P2434】【Noi2011】【阿狸的打字机】【题解】【fail树+dfs序+树状数组】

来源:互联网 发布:华育软件骗局 编辑:程序博客网 时间:2024/05/16 02:02

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2434

题解很多我就不讲了

Code:

#include<bits/stdc++.h>#define idx(c) (c-'a')#define lowbit(x) (x&-x)using namespace std;const int maxn=1e5+5;typedef pair<int,int> pi;vector<int>d,lef,rig;vector<pi>Q[maxn];char s[maxn];int n,m,len,anss[maxn],tot,mp[maxn],vmp[maxn];struct node{int val,id;node *go[26],*fail,*last,*pre;vector<node*>son;node(node *C=0){for(int i=0;i<26;i++)go[i]=C;fail=last=C;pre=C;id=0;val=0;}}*Null,*root;int cnt=0;node *newnode(){node *x=new node(Null);x->id=++cnt;return x;}void build(){Null=newnode();Null->fail=Null->last=Null;for(int i=0;i<26;i++)Null->go[i]=Null;root=Null;node *u=root;for(int i=0;i<len;i++){if(s[i]=='B'){u=u->pre;continue;}if(s[i]=='P'){++n;mp[n]=u->val?mp[u->val]:n;u->val=u->val?u->val:n;vmp[u->val]=u->id;continue;}int v=idx(s[i]);if(u->go[v]==Null)u->go[v]=newnode();u->go[v]->pre=u;u=u->go[v];}}void get_fail(){queue<node*>q;for(int i=0;i<26;i++)if(root->go[i]!=Null)q.push(root->go[i]),root->son.push_back(root->go[i]);while(!q.empty()){node *u=q.front(),*v;q.pop();for(int i=0;i<26;i++)if((v=u->go[i])!=Null){q.push(v);node *j=u->fail;while(j!=Null&&j->go[i]==Null)j=j->fail;v->fail=j->go[i];j->go[i]->son.push_back(v);v->last=v->fail->val?v->fail:v->last;}}}int get(int x){int ans=0;while(x)ans+=d[x],x-=lowbit(x);return ans;}void updata(int x,int f){while(x<d.size())d[x]+=f,x+=lowbit(x);}void _dfs(node *u){lef[u->id]=++tot;for(int i=0;i<u->son.size();i++)_dfs(u->son[i]);rig[u->id]=tot;}void dfs(node *u){updata(lef[u->id],1);for(int i=0;i<Q[u->val].size();i++)anss[Q[u->val][i].second]=get(rig[vmp[Q[u->val][i].first]])-get(lef[vmp[Q[u->val][i].first]]-1);for(int i=0;i<26;i++)if(u->go[i]!=Null)dfs(u->go[i]);updata(lef[u->id],-1);}int main(){scanf("%s",s);len=strlen(s);build();get_fail();d.resize(cnt+1);lef.resize(cnt+1);rig.resize(cnt+1);_dfs(root);scanf("%d",&m);for(int i=1;i<=m;i++){int x,y;scanf("%d%d",&x,&y);Q[mp[y]].push_back(make_pair(mp[x],i));}dfs(root);for(int i=1;i<=m;i++)printf("%d\n",anss[i]);return 0;}


0 0
原创粉丝点击