• 【BZOJ2555】SubString


    题面

    http://darkbzoj.tk/problem/2555

    题解

    $LCT$ 维护子树权值和。

    注意 $makeroot(x)$ 是真的 $makeroot$。(能看懂的人应该都看懂了)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #define ri register int
    #define N 600050
    using namespace std;
    
    int mask;
    int q;
    char s[N],s0[N];
    char tmp[N];
    int cnt[N<<1];
    
    void trans(int mask) {
      int n=strlen(s);
      for (ri i=0;i<n;i++) {
        mask=(mask*131+i)%n;
        swap(s[i],s[mask]);
      }
    }
    
    struct LinkCutTree {
      int sum[N<<1],sumi[N<<1],ch[N<<1][2];
      int fa[N<<1];
      bool rev[N<<1];
      int stk[N<<1],top;
      
      bool notroot(int x) {
        return ch[fa[x]][0]==x || ch[fa[x]][1]==x;
      }
      bool opt(int x) {
        return ch[fa[x]][1]==x;
      }
      void update(int x) {
        sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+sumi[x]+cnt[x];
      }
      void pushr(int x) {
        if (!rev[x]) return;
        rev[x]=0;
        swap(ch[x][0],ch[x][1]);
        if (ch[x][0]) rev[ch[x][0]]^=1;
        if (ch[x][1]) rev[ch[x][1]]^=1;
      }
      
      void rotate(int x) {
        //printf("ROTATE %d
    ",x);
        int y=fa[x],z=fa[y],s=opt(x),w=ch[x][1^s];
        fa[x]=z; if (notroot(y)) ch[z][opt(y)]=x;
        if (w) fa[w]=y; ch[y][s]=w;
        ch[x][1^s]=y; fa[y]=x;
        update(y); update(x);
      }
      
      void splay(int x) {
        //printf("SPLAY %d
    ",x);
        top=1; int y=x;
        while (notroot(y)) stk[top++]=y,y=fa[y]; stk[top]=y;
        while (top) pushr(stk[top]),top--;
        while (notroot(x)) {
          if (!notroot(fa[x])) rotate(x);
          else {
            if (opt(x)==opt(fa[x])) rotate(fa[x]); else rotate(x);
            rotate(x);
          }
        }
      }
      
      void access(int x) {
        //printf("ACCESS %d
    ",x);
        int y=0;
        while (x) {
          splay(x);
          sumi[x]+=sum[ch[x][1]];
          sumi[x]-=sum[ch[x][1]=y];
          update(x);
          y=x; x=fa[x];
        }
      }
      
      void makeroot(int x) {
        //printf("MAKEROOT %d
    ",x);
        access(x); splay(x);
        rev[x]^=1; pushr(x);
      }
      
      void link(int x,int ff) {
        //printf("LINK %d %d
    ",x,ff);
        makeroot(x);
        access(ff);
        splay(ff);
        fa[x]=ff;
        sumi[ff]+=sum[x];
        update(ff);
      }
      
      void cut(int x,int ff) {
        //printf("CUT %d %d
    ",x,ff);
        makeroot(ff);
        access(x);
        splay(x);
        ch[x][opt(ff)]=fa[ff]=0;
        update(x);
      }
      
      int query(int x) {
        if (!x) return 0;
        makeroot(1);
        access(x);
        return sum[x]-sum[ch[x][0]]-sum[ch[x][1]];
      }
    } lct;
    
    struct SuffixAutoMachine {
      int len[N<<1],ff[N<<1];
      int ch[N<<1][26];
      int ton[N<<1],a[N<<1];
      int aaa[N<<1];
      int las,tot;
      inline void init() {tot=las=1;}
      inline void extend(int c) {
        int p=las,np=++tot; las=np;
        cnt[np]=1;
        len[np]=len[p]+1;
        while (p && !ch[p][c]) ch[p][c]=np,p=ff[p];
        if (!p) ff[np]=1;
        else {
          int q=ch[p][c];
          if (len[q]==len[p]+1) ff[np]=q;
          else {
            int nq=++tot;
            for (ri i=0;i<26;i++) ch[nq][i]=ch[q][i]; ff[nq]=ff[q]; len[nq]=len[p]+1;
            lct.link(nq,ff[nq]);
            lct.cut(q,ff[q]);
            ff[np]=ff[q]=nq;
            lct.link(q,ff[q]);
            while (p && ch[p][c]==q) ch[p][c]=nq,p=ff[p];
          }
        }
        lct.link(np,ff[np]);
      }
      int find() {
        int now=1;
        for (ri i=0,l=strlen(s);i<l;i++) now=ch[now][s[i]-'A'];
        return now;
      }
    } sam;
    
    int main(){
      scanf("%d",&q);
      scanf("%s",s); sam.init();
      for (ri i=0,l=strlen(s);i<l;i++) sam.extend(s[i]-'A');
      for (ri j=1;j<=q;j++) {
        scanf("%s",s0);
        if (s0[0]=='Q') {
          scanf("%s",s); trans(mask);
          int p=sam.find();
          int ans2=lct.query(p);
          printf("%d
    ",ans2);
          mask^=ans2;
        }
        else {
          scanf("%s",s); trans(mask);
          for (ri i=0,l=strlen(s);i<l;i++) sam.extend(s[i]-'A');
        }
      }
    }
  • 相关阅读:
    CORS详解
    JBoss 系列九十九:Rest WebService jBPM 6 集成演示样例
    atitit。浏览器缓存机制 and 微信浏览器防止缓存的设计 attilax 总结
    4G时代来临,运营商为谁搭台献唱?
    Pascal&#39;s Triangle II
    cocos2d-x 3.6版连连看载入资源
    SlidingMenu导入编译用法--Eclipse和IDEA
    【解决】hive动态添加partitions不能超过100的问题
    AngularJS clone directive 指令复制
    AndroidStudio文件夹结构视图讲解
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11279188.html
Copyright © 2020-2023  润新知