CodeForces 547E Mike and Friends [Fail树+树状数组]
来源:互联网 发布:逆波兰算法 编辑:程序博客网 时间:2024/05/21 02:20
Description
What-The-Fatherland is a strange country! All phone numbers there are strings consisting of lowercase English letters. What is double strange that a phone number can be associated with several bears!
In that country there is a rock band called CF consisting of n bears (including Mike) numbered from 1 to n.
Phone number of i-th member of CF is si. May 17th is a holiday named Phone Calls day. In the last Phone Calls day, everyone called all the numbers that are substrings of his/her number (one may call some number several times). In particular, everyone called himself (that was really strange country).
Denote as call(i, j) the number of times that i-th member of CF called the j-th member of CF.
The geek Mike has q questions that he wants to ask you. In each question he gives you numbers l, r and k and you should tell him the number
题意:给出N个串,M个询问,对于每个询问L,R,K,给出串L到串R的所有串中串K作为子串出现了几次。
解法:根据正解重新写了一遍,将N个串插入AC自动机,再根据Fail指针重新构建Fail树,可知Fail树有性质父节点都是其子节点的最长的非本身后缀,且其为某串前缀,故而父节点都是子节点所在串的子串,有了这一性质,可以搞出Fail树的DFS序,然后变成了统计子树内,所代表串的编号在L,R内的所有节点的权值和,很明显可以离线树状数组搞,如果要在线处理询问,可以用主席树。
代码: (离线树状数组,500MS左右,比SA写法快了几倍...)
#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#include<iostream>#include<stdlib.h>#include<set>#include<map>#include<queue>#include<vector>#include<bitset>#pragma comment(linker, "/STACK:1024000000,1024000000")template <class T>bool scanff(T &ret){ //Faster Input char c; int sgn; T bit=0.1; if(c=getchar(),c==EOF) return 0; while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); if(c==' '||c=='\n'){ ret*=sgn; return 1; } while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10; ret*=sgn; return 1;}#define inf 1073741823#define llinf 4611686018427387903LL#define PI acos(-1.0)#define lth (th<<1)#define rth (th<<1|1)#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)#define mem(x,val) memset(x,val,sizeof(x))#define mkp(a,b) make_pair(a,b)#define findx(x) lower_bound(b+1,b+1+bn,x)-b#define pb(x) push_back(x)using namespace std;typedef long long ll;typedef pair<int,int> pii;#define NN 500500int tot,q[NN],nxt[NN][26],fail[NN],fa[NN];int ptx[NN],lnum,last[NN];struct edge{ int v,next; edge(){} edge(int v,int next){ this->v=v; this->next=next; }}ed[NN*2];void addedge(int x,int y){ ed[lnum]=edge(y,ptx[x]); ptx[x]=lnum++;}void insert(int x,char *s){ int len=strlen(s); int root=1; rep(i,0,len-1){ int idx=s[i]-'a'; if(!nxt[root][idx]){ nxt[root][idx]=++tot; fa[tot]=root; } root=nxt[root][idx]; } last[x]=root;}void getfail(){ int head=0,tail=0; q[tail++]=1; while(head<tail){ int x=q[head++]; if(fail[x]){ addedge(x,fail[x]); addedge(fail[x],x); } rep(i,0,25){ if(!nxt[x][i])nxt[x][i]=nxt[fail[x]][i]; else{ fail[nxt[x][i]]=nxt[fail[x]][i]; q[tail++]=nxt[x][i]; } } }}void init(){ tot=1; rep(i,0,25)nxt[0][i]=1; mem(ptx,-1);}int pos[NN],lx[NN],rx[NN],cot;void dfs(int x,int fa){ pos[++cot]=x; lx[x]=cot; gson(i,x){ int y=ed[i].v; if(y==fa)continue; dfs(y,x); } rx[x]=cot;}int ans[NN];struct node{ int l,r,idx; node(){} node(int l,int r,int idx){ this->l=l; this->r=r; this->idx=idx; }};vector < node > q1[NN],q2[NN];int c[NN];#define lowbit(x) (x&(-x))void add(int x,int val){ for(int i=x;i<=tot;i+=lowbit(i))c[i]+=val;}int getsum(int x){ int sum=0; while(x){ sum+=c[x]; x-=lowbit(x); } return sum;}int n,qn;char s[NN];int main(){ init(); scanff(n); scanff(qn); rep(i,1,n){ scanf("%s",s); insert(i,s); } getfail(); dfs(1,0); rep(i,1,qn){ int l,r,k; scanff(l); scanff(r); scanff(k); q1[l].pb(node(lx[last[k]],rx[last[k]],i)); q2[r].pb(node(lx[last[k]],rx[last[k]],i)); } rep(i,1,n){ int x=last[i]; while(x)add(lx[x],1),x=fa[x]; rep(j,0,q1[i+1].size()-1) ans[q1[i+1][j].idx]-=getsum(q1[i+1][j].r)-getsum(q1[i+1][j].l-1); } rep(i,1,n){ rep(j,0,q1[i].size()-1) ans[q1[i][j].idx]+=getsum(q1[i][j].r)-getsum(q1[i][j].l-1); } mem(c,0); drep(i,n,1){ int x=last[i]; while(x)add(lx[x],1),x=fa[x]; rep(j,0,q2[i-1].size()-1) ans[q2[i-1][j].idx]-=getsum(q2[i-1][j].r)-getsum(q2[i-1][j].l-1); } rep(i,1,qn) printf("%d\n",ans[i]); return 0;}
- CodeForces 547E Mike and Friends [Fail树+树状数组]
- 【codeforces】Codeforces Round #305 (Div. 1)E. Mike and Friends【后缀数组+线段树】
- Codeforces Round #305 (Div. 1)E. Mike and Friends 后缀数组+RMQ+线段树
- Codeforces Round #305 (Div. 1)E. Mike and Friends【后缀数组+线段树】
- CodeForces 547E Mike and Friends [后缀树组+主席树]
- 字符串k在第li到第ri个字符串中一共出现了几次 后缀数组+线段树 Codeforces Div. 1E. Mike and Friends
- 【后缀自动机】Codeforces Round #305 (Div. 1) E. Mike and Friends
- CodeForces 658B Bear and Displayed Friends(树状数组)
- 【codeforces 548E】Mike and Foam
- CodeForces 315E - Sereja and Subsequences 阅读理解+树状数组
- Codeforces 387E George and Cards(二分+树状数组)
- George and Cards - CodeForces 387E 树状数组
- CodeForces - 369E Valera and Queries 离线+树状数组
- Codeforces 369E Valera and Queries --树状数组+离线操作
- CodeForces - 369E Valera and Queries(树状数组)
- Codeforces 387E George and Cards(二分+树状数组)
- CodeForces 669E Little Artem and Time Machine(主席树+树状数组)
- Codeforces 276E(树状数组)
- Jquery easyui从零单排之datagrid整表编辑保存到数据库
- EXT.NET与Echart结合
- Android实现Material Design风格的设置页面(滑动开关控件)
- 释放文件到临时文件夹中所引发的安全问题
- mysql免安装版本
- CodeForces 547E Mike and Friends [Fail树+树状数组]
- supernova学习笔记
- OpenCV对鼠标事件的处理
- php 做下载功能需注意项
- iOS开发——iOS状态栏和导航栏的控制问题
- App 开发:Hybrid 架构下的 HTML5 应用加速方案
- iOS-私有API与runtime
- linux下mysql出现中文乱码(中文问号)
- 自定义控件三部曲之动画篇(十)——联合动画的XML实现与使用示例