您的位置:首页 > 大数据 > 人工智能

[AC自动机 fail树 树状数组] BZOJ 2434 [NOI2011] 阿狸的打字机

2016-07-21 08:36 597 查看
PoPoQQQ:http://blog.csdn.net/popoqqq/article/details/41518097

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: