BZOJ 2434 阿狸的打字机
Posted ziliuziliu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 2434 阿狸的打字机相关的知识,希望对你有一定的参考价值。
题解网上都有。。。要注意下细节。。。
#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; }
以上是关于BZOJ 2434 阿狸的打字机的主要内容,如果未能解决你的问题,请参考以下文章