您的位置:首页 > 其它

[后缀自动机 LCT] BZOJ 2555 SubString

2017-01-28 21:26 423 查看
构建后缀自动机 parent树会改变形态 这样|right(x)|也会发生变化

我们用LCT大力维护一发就好了

#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;
}

inline int read(char *s){
char c=nc(); int len=0;
for (;!(c>='A' && c<='Z');c=nc()) if (c==EOF) return 0;
for (;c>='A' && c<='Z';s[++len]=c,c=nc()); s[++len]=0; return len-1;
}

const int N=1200005;

struct Splay{
#define ls ch[x][0]
#define rs ch[x][1]
int val
,ch
[2],fat
,add
;
inline int dir(int x){return ch[fat[x]][1]==x;}
inline int isroot(int x){return ch[fat[x]][0]!=x&&ch[fat[x]][1]!=x;}
inline void mark(int x,int v){add[x]+=v,val[x]+=v;}
inline void pushdown(int x){
if (add[x]!=0){
if (ls) mark(ls,add[x]);
if (rs) mark(rs,add[x]);
add[x]=0;
}
}
void relax(int x){if (!isroot(x)) relax(fat[x]);pushdown(x);}
void rotate(int x){
int y=fat[x],z=fat[y],nx=dir(x),ny=dir(y),isrt=isroot(y);
fat[ch[x][!nx]]=y,ch[y][nx]=ch[x][!nx];
fat[x]=z;if (!isrt) ch[z][ny]=x;
fat[y]=x,ch[x][!nx]=y;
}
void splay(int x){
relax(x);
while (!isroot(x)){
int y=fat[x];
if (isroot(y)) rotate(x);
else if (dir(x)==dir(y)) rotate(y),rotate(x);
else rotate(x),rotate(x);
}
}
void access(int x){
for (int p=0;x;x=fat[x])
splay(x),rs=p,p=x;
}
void link(int x,int f){
fat[x]=f,access(f),splay(f),mark(f,val[x]);
}
void cut(int x){
access(x),splay(x),mark(ls,-val[x]);
fat[ls]=0,ls=0;
}
#undef ls
#undef rs
}LCT;

struct state{
int len,link,next[26];
}st
;
int ncnt,last;

inline void Extend(char c){
int cur=++ncnt,p; c-='A';
st[cur].len=st[last].len+1; LCT.val[cur]=1;
for (p=last;p!=-1 && !st[p].next[c];p=st[p].link)
st[p].next[c]=cur;
if (p==-1)
st[cur].link=1,LCT.link(cur,1);
else{
int q=st[p].next[c];
if (st[q].len==st[p].len+1)
st[cur].link=q,LCT.link(cur,q);
else{
int nq=++ncnt;
st[nq].len=st[p].len+1;
st[nq].link=st[q].link;
LCT.cut(q); LCT.link(nq,st[q].link);
memcpy(st[nq].next,st[q].next,sizeof(st[q].next));
for (;p!=-1 && st[p].next[c]==q;p=st[p].link)
st[p].next[c]=nq;
st[q].link=st[cur].link=nq;
LCT.link(q,nq); LCT.link(cur,nq);
}
}
last=cur;
}

int n; char S
;

inline void decode(int mask){
for (int i=1;i<=n;i++){
mask=(mask*131+i-1)%n;
swap(S[i],S[mask+1]);
}
}

int main(){
int Q,mask=0; char order[15];
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(Q); n=read(S);
ncnt=last=1; st[1].link=-1;
for (int i=1;i<=n;i++)
Extend(S[i]);
while (Q--){
read(order); n=read(S); decode(mask);
if (order[1]=='A'){
for (int i=1;i<=n;i++)
Extend(S[i]);
}else{
int p=1,ans=-1;
for (int i=1;i<=n;i++){
if (!st[p].next[S[i]-'A']) { ans=0; break; }
p=st[p].next[S[i]-'A'];
}
if (ans==-1)
LCT.splay(p),ans=LCT.val[p];
printf("%d\n",ans);
mask^=ans;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: