• CF452E Three strings 广义后缀自动机


    建一个广义后缀自动机统计一下就行,好长时间不敲后缀自动机调了半天~

    #include <bits/stdc++.h>
    using namespace std; 
    namespace IO {
        void setIO(string s) {
            string in=s+".in"; 
            freopen(in.c_str(),"r",stdin); 
        } 
    }; 
    #define ll long long 
    const int maxn=600004;   
    const ll mod=1000000007;    
    int last,tot; 
    int ch[maxn][30],f[maxn],len[maxn],n[4],rk[maxn],tax[maxn];     
    ll answer[maxn], cnt[maxn][4];    
    char A[maxn];       
    void extend(int c,int i) {          
        int p=last;   
        if(ch[p][c]) {       
            int q=ch[p][c]; 
            if(len[q]==len[p]+1) last=q;   
            else {
                int nq=++tot;                  
                last=nq,len[nq]=len[p]+1;    
                memcpy(ch[nq],ch[q],sizeof(ch[q]));   
                f[nq]=f[q],f[q]=nq;       
                while(p&&ch[p][c]==q) ch[p][c]=nq,p=f[p];  
            }
        }
        else {
            int np=++tot;       
            len[np]=len[p]+1,last=np; 
            while(p&&!ch[p][c]) ch[p][c]=np,p=f[p]; 
            if(!p) f[np]=1; 
            else {
                int q=ch[p][c];    
                if(len[q]==len[p]+1) f[np]=q; 
                else {
                    int nq=++tot;    
                    len[nq]=len[p]+1;    
                    memcpy(ch[nq],ch[q],sizeof(ch[q]));   
                    f[nq]=f[q],f[np]=f[q]=nq;       
                    while(p&&ch[p][c]==q) ch[p][c]=nq,p=f[p];      
                }
            }    
        }
        ++cnt[last][i];  
    }
    int main() { 
        // IO::setIO("input"); 
        last=tot=1; 
        int i,j; 
        for(i=0;i<3;++i) {
            scanf("%s",A+1), n[i]=strlen(A+1),last=1;     
            for(j=1;j<=n[i];++j) extend(A[j]-'a',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;     
        for(i=tot;i>=2;--i) {
            int cur=rk[i];    
            for(j=0;j<3;++j) cnt[f[cur]][j]+=cnt[cur][j];      
            ll now=cnt[cur][0]*cnt[cur][1]%mod*cnt[cur][2]%mod;     
            answer[len[f[cur]]+1]=(answer[len[f[cur]]+1]+now)%mod;   
            answer[len[cur]+1]=(answer[len[cur]+1]-now+mod)%mod;       
        }
        for(i=1;i<=tot;++i) answer[i]+=answer[i-1],answer[i]%=mod; 
        for(i=1;i<=min(n[0],min(n[1],n[2]));++i) printf("%lld ",answer[i]); 
        return 0; 
    }
    

      

  • 相关阅读:
    【NOIP2016】换教室
    【NOIP模拟赛】总结
    【Codeforces Round 418】An impassioned circulation of affection DP
    DP测试总结
    【NOIP2012】疫情控制
    【HNOI2016】序列 莫队+单调栈+RMQ
    【Luogu P2709 小B的询问】莫队
    【HNOI2017】影魔
    【HNOI2017】大佬
    阿里云MaxCompute 2019-7月刊
  • 原文地址:https://www.cnblogs.com/guangheli/p/11302954.html
Copyright © 2020-2023  润新知