• CF547E Mike and Friends 后缀自动机+线段树合并


    裸题,敲完后没调就过了 ~ 

    code: 

    #include <bits/stdc++.h>  
    using namespace std;
    #define ll long long 
    #define lson t[x].ls 
    #define rson t[x].rs  
    #define setIO(s) freopen(s".in","r",stdin)  
    const int N=200006;    
    char str[N];  
    int tax[N<<1],rk[N<<1];   
    int n,tot=1,cnt,last,pre[N<<1],ch[N<<1][26],mx[N<<1],rt[N<<1],id[N<<1];              
    struct node 
    {  
        ll sum; 
        int ls,rs; 
    }t[N*30];    
    int newnode() 
    {
        return ++ cnt; 
    }   
    void update(int &x,int l,int r,int p,int v) 
    {
        if(!x)   x=newnode();    
        t[x].sum+=v;   
        if(l==r)   return; 
        int mid=(l+r)>>1;    
        if(p<=mid)   update(lson,l,mid,p,v); 
        else update(rson,mid+1,r,p,v);    
    }
    int merge(int x,int y) 
    {
        if(!x||!y)   return x+y;   
        int now=newnode();    
        t[now].sum=t[x].sum+t[y].sum; 
        t[now].ls=merge(t[x].ls,t[y].ls); 
        t[now].rs=merge(t[x].rs,t[y].rs);  
        return now;  
    }   
    ll query(int x,int l,int r,int L,int R) 
    {
        if(l>=L&&r<=R) return t[x].sum;  
        ll re=0; 
        int mid=(l+r)>>1; 
        if(L<=mid)   re+=query(lson,l,mid,L,R); 
        if(R>mid)    re+=query(rson,mid+1,r,L,R); 
        return re; 
    }
    void Insert(int c) 
    {           
        if(ch[last][c]) 
        { 
            int p=last,q=ch[last][c];      
            if(mx[q]==mx[p]+1)  last=q;  
            else 
            {
                int nq=++tot;     
                last=nq; 
                mx[nq]=mx[p]+1;  
                memcpy(ch[nq],ch[q],sizeof(ch[q]));    
                pre[nq]=pre[q],pre[q]=nq;  
                for(;p&&ch[p][c]==q;p=pre[p])    ch[p][c]=nq; 
            }
        }
        else 
        {   
            int p=last,np=++tot; 
            mx[np]=mx[p]+1,last=np;  
            for(;p&&!ch[p][c];p=pre[p])   ch[p][c]=np; 
            if(!p)   pre[np]=1;  
            else 
            {
                int q=ch[p][c]; 
                if(mx[q]==mx[p]+1)   pre[np]=q; 
                else 
                {
                    int nq=++tot; 
                    mx[nq]=mx[p]+1;  
                    memcpy(ch[nq],ch[q],sizeof(ch[q]));  
                    pre[nq]=pre[q],pre[np]=pre[q]=nq;  
                    for(;p&&ch[p][c]==q;p=pre[p])   ch[p][c]=nq;  
                }
            }
        }  
    } 
    void M() 
    { 
        int i,j; 
        for(i=2;i<=tot;++i)      ++tax[mx[i]];   
        for(i=1;i<=tot;++i)      tax[i]+=tax[i-1];  
        for(i=1;i<=tot;++i)      rk[tax[mx[i]]--]=i;     
        for(i=tot;i>1;--i) 
        {
            int u=rk[i];  
            int ff=pre[u];  
            rt[ff]=merge(rt[ff],rt[u]);   
        }   
    }
    int main() 
    {
        // setIO("input");      
        int i,j,m; 
        scanf("%d%d",&n,&m); 
        for(i=1;i<=n;++i) 
        {   
            scanf("%s",str+1);
            int len=strlen(str+1); last=1;      
            for(j=1;j<=len;++j)   Insert(str[j]-'a'),update(rt[last],1,n,i,1);   
            id[i]=last;  
        }   
        M();    
        for(i=1;i<=m;++i) 
        {
            int l,r,k; 
            scanf("%d%d%d",&l,&r,&k);     
            printf("%lld
    ",query(rt[id[k]],1,n,l,r));  
        }  
        return 0; 
    }
    

      

  • 相关阅读:
    学渣逆袭回忆录:0序
    selenium和Firefox版本不兼容
    学习Python的第一课(简单的单元测试)
    C# 实现模拟登录功能,实现公共类分享。
    MVC之权限管理-网站开发之路
    程序员学习之路
    【数据结构】浅谈线性数据结构
    【数据结构】二叉堆
    tire 学习心得
    洛谷P1801 黑匣子
  • 原文地址:https://www.cnblogs.com/guangheli/p/11949800.html
Copyright © 2020-2023  润新知