[AC自动机 fail树 树状数组] BZOJ 2434 [NOI2011] 阿狸的打字机
2016-07-21 08:36
597 查看
PoPoQQQ:http://blog.csdn.net/popoqqq/article/details/41518097
fail树不难想 看到两个条件马上想到树套树 汗
后来发现可以离线 树状数组
fail树不难想 看到两个条件马上想到树套树 汗
后来发现可以离线 树状数组
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } const int N=100005; namespace BIT{ int maxn,c ; inline void init(int n){ maxn=n; } inline void add(int x,int r){ for (int i=x;i<=maxn;i+=i&-i) c[i]+=r; } inline int sum(int x){ int ret=0; for (int i=x;i;i-=i&-i) ret+=c[i]; return ret; } inline int sum(int l,int r){ return sum(r)-sum(l-1); } } struct edge{ int u,v,next; int idx; }G[N<<2]; int head ,inum; int first ; inline void add(int u,int v,int p,int *head=::head,int idx=0){ G[p].u=u; G[p].v=v; G[p].idx=idx; G[p].next=head[u]; head[u]=p; } int pre ,size ,clk; #define V G[p].v inline void dfs(int u){ pre[u]=++clk; size[u]=1; for (int p=head[u];p;p=G[p].next) dfs(V),size[u]+=size[V]; } char S ; int Len; int root,ncnt,ch [26]; int val ,f ; int Q ,l,r; inline void GetFail() { f[0]=0; l=r=-1; int u,v,t; for (int i=0;i<26;i++) if (ch[0][i]) f[ch[i][0]]=0,Q[++r]=ch[0][i]; while (l<r) { int u=Q[++l]; for (int i=0;i<26;i++) { v=ch[u][i]; if (!v) continue; Q[++r]=v; t=f[u]; while (t && !ch[t][i]) t=f[t]; f[v]=ch[t][i]; } } for (int i=r;~i;i--) add(f[Q[i]],Q[i],++inum); dfs(0); BIT::init(clk); } int icnt,pos ; int Sta ,pnt; int T,ans ; int main() { int ix,iy; freopen("t.in","r",stdin); freopen("t.out","w",stdout); scanf("%s",S+1); Len=strlen(S+1); Sta[++pnt]=root; for (int i=1;i<=Len;i++) if (S[i]>='a' && S[i]<='z'){ int p=Sta[pnt]; if (!ch[p][S[i]-'a']) ch[p][S[i]-'a']=++ncnt; Sta[++pnt]=ch[p][S[i]-'a']; }else if (S[i]=='P'){ pos[++icnt]=Sta[pnt]; }else if (S[i]=='B'){ pnt--; } GetFail(); read(T); for (int i=1;i<=T;i++) read(ix),read(iy),add(iy,ix,++inum,first,i); pnt=0; Sta[++pnt]=root; icnt=0; for (int i=1;i<=Len;i++) if (S[i]>='a' && S[i]<='z'){ int p=ch[Sta[pnt]][S[i]-'a']; Sta[++pnt]=p; BIT::add(pre[p],1); }else if (S[i]=='P'){ for (int p=first[++icnt];p;p=G[p].next) ans[G[p].idx]=BIT::sum(pre[pos[V]],pre[pos[V]]+size[pos[V]]-1); }else if (S[i]=='B'){ int p=Sta[pnt]; BIT::add(pre[p],-1); pnt--; } for (int i=1;i<=T;i++) printf("%d\n",ans[i]); return 0; }
相关文章推荐
- [AC自动机 fail树 || 后缀数组] BZOJ 3172 [Tjoi2013]单词
- Codeforce 2016 Al-Baath University Training Camp Contest-1
- UVa 11374 Airport Express
- 深入分析AIL语言及init.rc文件
- VirtualBox 出现“Failed to attach the network LUN”错误的解决方案
- ecshop网页加载waiting(TTFB)时间过长的解决方法
- ADK - SnowMountain场景制作(一)
- 2016 Multi-University Training Contest 1-1011---HDU 5733 tetrahedron(计算几何)
- [70] Climbing Stairs
- Number of Airplanes in the Sky
- vim 经典配色 molokai.vim 配色安装
- LeetCode - 172. Factorial Trailing Zeroes
- (11) ejb学习: Jpa事务管理类型 container 和 bean
- rdd.filter(_.contains("1")).count()详解
- df 命令结果显示的 Size 不等于 Avail + Used
- df 命令结果显示的 Size 不等于 Avail + Used
- Visual Studio 2015 update 2 setup fails with "missing or damaged package kb3022398"
- 【2016 Multi-University Training Contest 1】【hdu5723】Abandoned Countries
- pair与排序
- 2015 Multi-University Training Contest 1_A(hdu 5288)