• 后缀树(BZOJ3238TLE)


    #include<cstdio>
    #include<cstring>
    #define LL long long 
    
     char st[500010],stt[500010];
     LL ans;
     int leafr,ndcnt=1,sidcnt,lastcre;
     int isleaf[1000010],dep[1000010],nd[1000010],l[1000010],r[1000010],des[1000010],
           next[1000010],sufchain[1000010];
    
      
     int getr(int sid){
         if (isleaf[des[sid]]) return(leafr);else return(r[sid]);
     }
     
     void cut(int po,int sid,int len){
         dep[++ndcnt]=dep[po]+len;
         isleaf[ndcnt]=0;
         
         nd[ndcnt]=++sidcnt;
         des[sidcnt]=des[sid];
         l[sidcnt]=len+l[sid];r[sidcnt]=getr(sid);next[sidcnt]=-1;des[sidcnt]=des[sid];
        des[sid]=ndcnt;r[sid]=len+l[sid]-1;
     }
     
     void ins(int po,int alph){
         dep[++ndcnt]=dep[po]+1;
         isleaf[ndcnt]=1;
         nd[ndcnt]=-1;
         
         l[++sidcnt]=alph;r[sidcnt]=alph;
         des[sidcnt]=ndcnt;next[sidcnt]=nd[po];nd[po]=sidcnt;
     }
    
     void buildtree(){
        int po=1,lastins=1;nd[1]=-1;sufchain[1]=1;int prom=0;
        
        for (int i=1;i<=strlen(st)-1;i++){
            leafr=i;int p,flag;
            prom=0;
            
            while (lastins<=i){
                
                while(1){
                    flag=0;
                    for (p=nd[po];p!=-1;p=next[p])
                    if (st[l[p]]==st[lastins+dep[po]]) break;
                    
                    if (p==-1){ins(po,i);
                               if (prom) sufchain[lastcre]=po;
                               prom=0;
                               lastcre=po;
                               break;}
                    if (i-lastins+1-dep[po]<=getr(p)-l[p]+1){
                        if (st[i]==st[l[p]+i-lastins-dep[po]]) 
                          {flag=1;
                          if (prom) sufchain[lastcre]=po;
                          prom=0;
                          lastcre=po;
                          break;}
                        if (st[i]!=st[l[p]+i-lastins-dep[po]]) {
                            cut(po,p,i-lastins-dep[po]);
                            if (prom) sufchain[lastcre]=ndcnt;
                            if (i-lastins-dep[po]>1) prom=1;else prom=0;
                            lastcre=ndcnt;sufchain[lastcre]=1;
                            ins(ndcnt,i);break;
                        }
                    }
                    if (i-lastins+1-dep[po]>getr(p)-l[p]+1) po=des[p];
                }
                if (flag) {break;}
                po=sufchain[po];lastins++;
          }
        }
     }
     
     int top=0;
     struct str{
         int po,fr;
         LL cnt,len; 
     }sta[500010];
     
          
         void pb(int ps,int le,int p){
             sta[++top].po=p;sta[top].len=le;sta[top].fr=ps;
             sta[top].cnt=0;
         }
         
        void pop(){
            if (isleaf[sta[top].po]) sta[top].cnt++;
            sta[sta[top].fr].cnt+=sta[top].cnt;
            top--;
        }
     
     void getans(){
         pb(0,0,1);top=1;
         
         int i=1;
         while (top>=i){
             int tp=i;
             for (int p=nd[sta[tp].po];p!=-1;p=next[p]) 
             pb(tp,getr(p)-l[p]+1,des[p]);
             i++;
         }
         
        while(top){
            ans-=sta[top].len*sta[top].cnt*(sta[top].cnt-1);
            pop();
        } 
     }
    
     int main(){
         scanf("%s",stt);
         
         LL len=strlen(stt);ans=(len-1)*len*(len+1)/2;
        
        st[0]=' ';
        strcat(stt,"$");strcat(st,stt);
        
        buildtree();
    
        getans();
        
        printf("%lld",ans);
      }

    注意某一个串对应点到后缀树根的深度是$O(n cdot sqrt{n})$的

  • 相关阅读:
    线程安全和非线程安全
    spring MVC和hibernate的结合
    Spring学习笔记1——基础知识 (转)
    bitset && Luogu 3674 小清新人渣的本愿
    luogu P3452 [POI2007]BIU-Offices
    每日刷题记录
    Codeforces Round #721 (Div. 2) B2. Palindrome Game (hard version)
    2019湘潭邀请赛A
    2021CCPC浙江省赛 B
    Codeforces Round #720 (Div. 2) D
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/5570901.html
Copyright © 2020-2023  润新知