CF316G3 Good Substrings 广义后缀自动机

太累了,刷刷水~ 

code: 

#include <bits/stdc++.h>   
#define N 500005   
#define LL long long 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;      
char str[N];
int last,tot;     
int pre[N],len[N],ch[N][27],L[N],R[N],tax[N],rk[N],cnt[N][13],tag[N];                
int extend(int c) 
{ 
    int p=last;  
    if(ch[p][c]) 
    {  
        int q=ch[p][c]; 
        if(len[q]==len[p]+1)  last=q;  
        else
        {
            int nq=++tot;  
            tag[nq]=tag[q];   
            len[nq]=len[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; 
            last=nq;     
        }
    }   
    else
    {  
        int np=++tot;   
        len[np]=len[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(len[q]==len[p]+1)  pre[np]=q;  
            else 
            {
                int nq=++tot;   
                tag[nq]=tag[q];      
                len[nq]=len[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;    
            }
        }
    }
    return last;    
}   
int main() 
{ 
    int n,i,j,m;  
    // setIO("input");           
    scanf("%s",str+1),n=strlen(str+1),last=tot=1;    
    for(i=1;i<=n;++i)   
    {
        int x=extend(str[i]-'a');        
        tag[x]=1;   
    }   
    scanf("%d",&m);   
    for(i=1;i<=m;++i)     
    {
        int len,l,r; 
        scanf("%s%d%d",str+1,&L[i],&R[i]),len=strlen(str+1);      
        for(last=j=1;j<=len;++j)  
        {
            int x=extend(str[j]-'a');     
            ++cnt[x][i];   
        }
    }   
    for(i=1;i<=tot;++i)   ++tax[len[i]];  
    for(i=1;i<=tot;++i)   tax[i]+=tax[i-1];     
    for(i=1;i<=tot;++i)   rk[tax[len[i]]--]=i;    
    LL ans=0ll;   
    for(i=tot;i>1;--i) 
    {
        int x=rk[i]; 
        int ff=pre[x];       
        tag[ff]|=tag[x];          
        for(j=1;j<=m;++j)  cnt[ff][j]+=cnt[x][j];     
        if(tag[x])          
        {    
            int flag=0; 
            for(j=1;j<=m;++j)   if(cnt[x][j]<L[j]||cnt[x][j]>R[j]) flag=1;             
            if(!flag) ans+=1ll*(len[x]-len[ff]);   
        }   
    } 
    printf("%lld
",ans);                
    return 0; 
}

  

原文地址:https://www.cnblogs.com/guangheli/p/11782830.html