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\n",query(rt[id[k]],1,n,l,r));  
    }  
    return 0; 
}

  

posted @ 2019-11-28 14:24  EM-LGH  阅读(155)  评论(0编辑  收藏  举报