bzoj2434 阿狸的打字机 fail树+树状数组
来源:互联网 发布:福建公安便民网络 编辑:程序博客网 时间:2024/05/17 20:13
啊为了这道题花了接近半天的时间……主要还是因为自己效率太低……以及太弱……
思路:
m个询问,每个询问x y 问x在y中出现多少次
y–包含串 x–被包含串
求第x个打印的字符串在第y个打印的字符串中出现了多少次。
先建造ac自动机及fail指针,再以fail的反指针建造fail树。
x在y中出现多少次 =查x字符串的末尾指向y的fail反指针有多少=是此时在x的子树中有多少y串中的点=统计子树和
还有一些需要注意的细节,具体看代码:
/************************************************************** Problem: 2434 User: DD_D Language: C++ Result: Accepted Time:668 ms Memory:16584 kb****************************************************************/#include<cstdio>#include<cstring>#include<queue>#include<algorithm>using namespace std;const int M=1e5+5,N=1e5+5; char s[N];int rt,ch[N][26],ptot,etot,m,len;int to[N],head[N],nxt[N],in[N],out[N],idc,c[N],ans[M],ed[N],fa[N];int fail[N];struct type{ int x,y,id;}a[M];int cmp(type a,type b){ return a.y!=b.y?a.y<b.y:a.x<b.x;}void build(){ int now=rt,cnt=0/**/; for(int i=1;i<=len;i++){ if(s[i]=='P') ed[++cnt]=now; else if(s[i]=='B') now=fa[now]; else if(ch[now][s[i]-'a']==-1) ch[now][s[i]-'a']=++ptot,fa[ptot]=now,now=ptot; else now=ch[now][s[i]-'a']; }}void get_fail(){ queue<int> q; fail[rt]=0; q.push(rt); //!!!!!建fail的时候一定要记得特判第一层!!! while(!q.empty()){ int now=q.front();q.pop(); for(int i=0;i<26;i++){ if(ch[now][i]!=-1) { q.push(ch[now][i]); fail[ch[now][i]]= now==0?0:ch[fail[now]][i]; } else ch[now][i]= now==0?0:ch[fail[now]][i]; } }}void adde(int u,int v){ to[++etot]=v; nxt[etot]=head[u]; head[u]=etot;}void dfs(int u){ in[u]=++idc; for(int i=head[u];i;i=nxt[i]) dfs(to[i]); out[u]=idc;}void init(){ ptot=0; memset(ch,-1,sizeof(ch));}void add(int x,int d){ for(int i=x;i<=idc;i+=i&(-i)) c[i]+=d;}int query(int l,int r){ int a1=0,a2=0; for(int i=l-1;i>=1;i-=i&(-i)) a1+=c[i]; for(int i=r;i>=1;i-=i&(-i)) a2+=c[i]; return a2-a1;}//solve的步骤://y完了后,要查x字符串的末尾指向它的fail反指针有多少,也就是此时在x的子树中//有多少y串中的点,也就是统计子树和 //不用担心x的子树里有除y以外其他串的原因:y字符串不是从P开始而是从头开始//所以现在没有因为B而被删的字符都属于y字符串 void solve(){ int now=rt,cnt=0,k=1; for(int i=1;i<=len;i++){ if(s[i]=='P'){ cnt++; if(cnt==a[k].y){ for(;a[k].y==cnt;k++) ans[a[k].id]=query(in[ed[a[k].x]],out[ed[a[k].x]]); } } else if(s[i]=='B') add(in[now],-1),now=fa[now]; else now=ch[now][s[i]-'a'],add(in[now],1); }}int main(){ init(); scanf("%s",s+1); len=strlen(s+1); build(); get_fail(); for(int i=1;i<=ptot;i++) adde(fail[i],i); dfs(rt); scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%d%d",&a[i].x,&a[i].y); a[i].id=i; } sort(a+1,a+1+m,cmp); solve(); for(int i=1;i<=m;i++) printf("%d\n",ans[i]); return 0;}
阅读全文
0 0
- bzoj2434 阿狸的打字机 fail树+树状数组
- [BZOJ2434]NOI2011阿狸的打字机|AC自动机|fail树|树状数组
- 【bzoj2434】[Noi2011]阿狸的打字机 AC自动机+fail树+dfs序+树状数组
- bzoj2434 阿狸的打字机NOI2011ac自动机+fail树+树状数组+dfs序详解
- 【AC自动机-fail树+离线+DFS序+树状数组】BZOJ2434(Noi2011)[阿狸的打字机]题解
- BZOJ2434【NOI2011】阿狸的打字机 <AC自动机+Fail树+树状数组>
- bzoj2434 [Noi2011]阿狸的打字机 ( AC自动机 & fail树 + 树状数组 + dfs序 )
- BZOJ2434 [Noi2011]阿狸的打字机 【AC自动机 + fail树 + 树状数组】
- fail树 【Noi2011】 阿狸的打字机 bzoj2434
- bzoj2434 阿狸的打字机 AC自动机&&树状数组
- 阿狸的打字机 AC自动机 FAIL树 树状数组
- BZOJ2434 [Noi2011]阿狸的打字机【AC自动机+dfs序+树状数组】
- [BZOJ2434][NOI2011]阿狸的打字机(AC自动机+树状数组)
- 【bzoj2434】【NOI2011】【阿狸的打字机】【AC自动机+dfs序+树状数组】
- bzoj2434(NOI2011).阿狸的打字机(AC自动机 && DFS序 && 树状数组)
- [BZOJ2434][NOI2011]阿狸的打字机(AC自动机+树状数组)
- bzoj2434 阿狸的打字机
- BZOJ 2434 NOI2011 阿狸的打字机 fail树+树状数组
- 程序猿生活大爆炸
- hdu 2057 A + B Again
- spring cloud 之eureka-server
- 一些题
- 7.约束
- bzoj2434 阿狸的打字机 fail树+树状数组
- pandas官方文档中cookbook(2)的split&building criteria翻译
- 基于pycaffe从零开始写mnist(第三篇)——生成deploy.prototxt,做最后的验证
- 多种方法实现多态!!!
- WebSacrab与SQL注入
- [ifrog] Round #19 B -- Buildings
- 【笔试题】CVTE C++开发岗笔试题7.29
- POJ 1661 Help Jimmy(动态规划--最短下降模板)
- HTML仿抽屉新闻