bzoj 2434: [Noi2011]阿狸的打字机
来源:互联网 发布:淘宝客服具体要求 编辑:程序博客网 时间:2024/06/05 06:18
题意:自己看
题解:AC自动机+树状数组
按照题意建出AC自动机。问x在y中出现多少次,就是y的有几个位置跳若干次fail可以到x。所以我们就可以建fail树,从fail到i建边,将y的点+1,统计x的子树的和。这个可以用dfs序+树状数组实现。
代码:
#include<bits/stdc++.h>#define pa pair<int,int>using namespace std;struct trie{ int s[26],fail,fa;}tr[100010];int tn=0,m,len,pos[100010],n=0,num=0,fst[100010],nn=0,l[100010],r[100010],sum[100010],ans[100010];char s[100010];struct edge{ int x,y,n;}e[100010];vector<pa>q[100010];void ins(int x,int y){ e[++num]={x,y,fst[x]}; fst[x]=num;}inline void btrie(){ int now=0; for(int i=0;i<len;i++) { if(s[i]=='B') now=tr[now].fa; else if(s[i]=='P') pos[++n]=now; else { if(!tr[now].s[s[i]-'a']) { tr[now].s[s[i]-'a']=++tn; tr[tn].fa=now; } now=tr[now].s[s[i]-'a']; } }}inline void bfail(){ queue<int>q; for(int i=0;i<26;i++) if(tr[0].s[i]) q.push(tr[0].s[i]); while(!q.empty()) { int x=q.front(); for(int i=0;i<26;i++) { if(!tr[x].s[i]) continue; int j=tr[x].fail; while(j&&!tr[j].s[i]) j=tr[j].fail; if(tr[j].s[i]) j=tr[j].s[i]; tr[tr[x].s[i]].fail=j; q.push(tr[x].s[i]); } q.pop(); }}inline void btree(){ for(int i=1;i<=tn;i++) ins(tr[i].fail,i);}void dfs(int x){ l[x]=++nn; for(int i=fst[x];i;i=e[i].n) { int y=e[i].y; dfs(y); } r[x]=nn;}int lb(int x){ return x&-x;}void add(int x,int y){ for(int i=x;i<=nn;i+=lb(i)) sum[i]+=y;}int get(int x){ if(x==0) return 0; int ans=0; for(int i=x;i>0;i-=lb(i)) ans+=sum[i]; return ans;}int main(){ scanf("%s%d",s,&m); len=strlen(s); btrie(); bfail(); btree(); dfs(0);/* for(int i=0;i<=tn;i++) { printf("i:%d fa:%d fail:%d s:",i,tr[i].fa,tr[i].fail); for(int j=0;j<26;j++) printf("%d ",tr[i].s[j]); puts(""); } for(int i=1;i<=num;i++) printf(" %d %d\n",e[i].x,e[i].y); for(int i=0;i<=tn;i++) printf(" %d %d\n",l[i],r[i]);*/ for(int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); q[y].push_back(make_pair(x,i)); } n=0; int now=0; for(int i=0;i<len;i++) { if(s[i]=='B') { add(l[now],-1); now=tr[now].fa; } else if(s[i]=='P') { n++; for(int j=0;j<q[n].size();j++) { ans[q[n][j].second]=get(r[pos[q[n][j].first]])-get(l[pos[q[n][j].first]]-1); } } else { now=tr[now].s[s[i]-'a']; add(l[now],1); }/* printf("now:%d\n",now); for(int i=1;i<=nn;i++) printf("%d ",get(i)-get(i-1)); puts("");*/ } for(int i=0;i<m;i++) printf("%d\n",ans[i]);}
阅读全文
0 0
- bzoj-2434: [Noi2011]阿狸的打字机
- bzoj 2434: [Noi2011]阿狸的打字机
- BZOJ 2434 [Noi2011]阿狸的打字机
- BZOJ 2434 [Noi2011]阿狸的打字机
- bzoj 2434 [Noi2011]阿狸的打字机
- bzoj 2434: [Noi2011]阿狸的打字机
- BZOJ 2434 [Noi2011]阿狸的打字机
- bzoj 2434: [Noi2011]阿狸的打字机
- bzoj 2434: [Noi2011]阿狸的打字机
- 【AC自动机】 BZOJ 2434 [Noi2011]阿狸的打字机
- BZOJ 2434 [Noi2011] 阿狸的打字机 Fail树
- 2434: [Noi2011]阿狸的打字机
- 2434: [Noi2011]阿狸的打字机
- 阿狸的打字机 NOI2011
- [Noi2011]阿狸的打字机
- NOI2011阿狸的打字机
- NOI2011阿狸的打字机
- 【NOI2011】阿狸的打字机
- 8469:特殊密码锁
- 大咖 | 车品觉:我们为什么要认识数据的本质
- 模型调参:压力也没那么大,试了一圈还是得靠贝叶斯
- 二维码扫描
- IP 语音
- bzoj 2434: [Noi2011]阿狸的打字机
- 自定义view 动态圆形有百分比
- 刷题#R11
- 苹果发布iOS 11.2新测试版:只为iPhone X
- 讲给Android程序员看的前端教程(17)——伪元素
- 基于开源项目搭建属于自己的技术堆栈
- 随机函数帮你实现家庭和睦
- 贝索斯一天赚70亿,超盖茨成新首富,李嘉诚真实财富能否跟他相比
- Java工程师为何如此火爆?