[bzoj2555] SubString

[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');
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_35923186/article/details/82891985