[bzoj2555] SubString
SAM+LCT动态维护right大小
这数据有毒。。。貌似N等于2e6才能过
- 代码
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2e6+5,SZ=26;
int null=0;
struct Splay{
int ch[2],fa;
int siz,add;
}t[N];
inline bool isroot(int x){return t[t[x].fa].ch[1]!=x&&t[t[x].fa].ch[0]!=x;}
inline int son(int x){return t[t[x].fa].ch[1]==x;}
inline void rotate(int x){
int f=t[x].fa,gf=t[t[x].fa].fa;
int a=son(x),b=son(x)^1;
if(!isroot(f))t[gf].ch[son(f)]=x;
t[x].fa=gf;
t[f].ch[a]=t[x].ch[b];t[t[x].ch[b]].fa=f;
t[x].ch[b]=f;t[f].fa=x;
}
inline void newsplay(int _sum,int pos){
t[pos].siz+=_sum;
}
inline void pushnow(int x,int _sum){t[x].siz+=_sum,t[x].add+=_sum;}
inline void pushdown(int x){
if(!isroot(x))pushdown(t[x].fa);
if(t[x].add){
if(t[x].ch[0])pushnow(t[x].ch[0],t[x].add);
if(t[x].ch[1])pushnow(t[x].ch[1],t[x].add);
t[x].add=0;
}
}
inline void splay(int x){
pushdown(x);
while(!isroot(x)){
int f=t[x].fa;
if(!isroot(f)){
if(son(x)^son(f))rotate(x);
else rotate(f);
}
rotate(x);
}
}
inline void access(int x){
int tmp=null;
while(x!=null){
splay(x);
t[x].ch[1]=tmp;
tmp=x;x=t[x].fa;
}
}
inline void link(int x,int y){
access(y);
splay(y);
t[x].fa=y;
pushnow(y,t[x].siz);
}
inline void cut(int x){
access(x);
splay(x);
pushnow(t[x].ch[0],-t[x].siz);
t[t[x].ch[0]].fa=null;
t[x].ch[0]=null;
}
struct SuffixAutomaton
{
struct node{int ch[SZ],fa,len,right;}nd[N];
int root,last,cnt;
inline int newnode(int _len=0){nd[++cnt].len=_len;return cnt;}
inline void init(){root=last=newnode(0);newsplay(0,1);}
inline void ins(int c){
int nq=newnode(nd[last].len+1),q=last;
newsplay(1,nq);
for(;q&&!nd[q].ch[c];q=nd[q].fa)nd[q].ch[c]=nq;
if(q==0){
nd[nq].fa=root;
link(nq,root);
}
else if(nd[nd[q].ch[c]].len==nd[q].len+1){
nd[nq].fa=nd[q].ch[c];
link(nq,nd[q].ch[c]);
}
else{
int np=newnode(nd[q].len+1),p=nd[q].ch[c];
newsplay(0,np);//"!
memcpy(nd[np].ch,nd[p].ch,sizeof(nd[p].ch));
nd[np].fa=nd[p].fa;
link(np,nd[p].fa);
nd[p].fa=nd[nq].fa=np;
cut(p);
link(p,np);
link(nq,np);
for(;q&&nd[q].ch[c]==p;q=nd[q].fa)nd[q].ch[c]=np;
}
last=nq;
}
}SAM;
char s[N],op[10];
int len,mask=0;
void decode(int m){
for(int i=0;i<len;i++){
m=(m*131+i)%len;
swap(s[i],s[m]);
}
}
int main()
{
SAM.init();
int q;
scanf("%d",&q);
scanf("%s",s);
len=strlen(s);
for(int i=0;i<len;i++)SAM.ins(s[i]-'A');
while(q--){
scanf("%s %s",op,s);
len=strlen(s);
decode(mask);
if(op[0]=='Q'){
bool flag=true;
int now=SAM.root;
for(int i=0;i<len;i++){
int c=s[i]-'A';
if(!SAM.nd[now].ch[c]){flag=false;break;}
now=SAM.nd[now].ch[c];
}
if(!flag){printf("0\n");continue;}
splay(now);
mask^=t[now].siz;
printf("%d\n",t[now].siz);
}
else{
for(int i=0;i<len;i++)SAM.ins(s[i]-'A');
}
}
}