• CF 434C Tachibana Kanade's Tofu[数位dp+AC自动机]


    • Solution

    //本代码压掉后两维 
    #include<cstdio>
    #define max(a,b) (a<b?b:a)
    using namespace std;
    inline void read(int &x){
        register char ch=getchar();x=0;
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    }
    const int N=205,M=505;
    const int mod=1e9+7;
    int n,m,K,cnt=1,a[N],b[N];int bfs[N];
    int v[N],fail[N],next[N][20],trans[N][20];
    int f[N][N][M];
    inline void insert(int l){
        int x,now=1;
        for(int i=1;i<=l;i++){
            read(x);
            if(!next[now][x]) next[now][x]=++cnt;
            now=next[now][x];
        }
        read(x);v[now]+=x;
    }
    inline void build_AC(){
        int l=0,r=0,x,y;
        for(int i=0;i<m;i++){
            if(next[1][i]){
                x=next[1][i];
                fail[x]=1;
                trans[1][i]=x;
                bfs[++r]=x;
            }
            else{
                trans[1][i]=1;
            }
        }
        while(l!=r){
            x=bfs[++l];
            v[x]+=v[fail[x]];
            for(int i=0,p;i<m;i++){
                if(next[x][i]){
                    y=next[x][i];
                    for(p=fail[x];p&&!next[p][i];p=fail[p]);
                    if(p) fail[y]=next[p][i];
                    else fail[y]=1;
                    trans[x][i]=y;
                    bfs[++r]=y;
                }
                else{
                    for(p=fail[x];p&&!next[p][i];p=fail[p]);
                    if(p) trans[x][i]=next[p][i];
                    else trans[x][i]=1;
                }
            }
        }
    }
    inline void Plus(int &x,int y){
        x+=y;
        if(x>=mod) x-=mod;
    }
    inline void prep(int bit){//无任何限制预处理 
        for(int i=1;i<=cnt;i++) f[0][i][0]=1;
        for(int i=1;i<=bit;i++){
            for(int j=1;j<=cnt;j++){
                for(int p=0,x;p<m;p++){
                    x=trans[j][p];
                    for(int k=v[x];k<=K;k++){
                        Plus(f[i][j][k],f[i-1][x][k-v[x]]);
                    }
                }
            }
        }
    }
    inline int work(int *a,bool flag){
        int x,y,w,ans=0;
        //取出最高位后,保证无前导零后,无限制 
        for(int i=1;i<a[0];i++){
            for(int j=1;j<m;j++){
                y=trans[1][j];
                w=v[y];
                for(int k=w;k<=K;k++){
                    Plus(ans,f[i-1][y][k-w]);
                }
            }
        }
        //走一遍上界,要保证无前导零 
        x=1;w=0;
        for(int i=1;i<=a[0];i++){
            for(int j=(i==1);j<a[i];j++){
                y=trans[x][j];
                for(int k=0;k<=K-(w+v[y]);k++){
                    Plus(ans,f[a[0]-i][y][k]);
                }
            }
            x=trans[x][a[i]];
            w+=v[x];
        }
        if(flag){//上界有否取 
            if(w<=K) Plus(ans,1);
        }
        return ans;
    }
    int main(){
        read(n);read(m);read(K);
        read(a[0]);for(int i=1;i<=a[0];i++) read(a[i]);
        read(b[0]);for(int i=1;i<=b[0];i++) read(b[i]);
        for(int i=1,l;i<=n;i++) read(l),insert(l);
        build_AC();prep(max(a[0],b[0]));
        printf("%d
    ",(work(b,1)-work(a,0)+mod)%mod);
        return 0;
    }

     

  • 相关阅读:
    【PHP设计模式 08_CeLue.php】策略模式
    【PHP设计模式 07_ZeRenLian.php】责任链模式
    【PHP设计模式 06_GuanChaZhe.php】观察者模式
    【PHP设计模式 05_DanLi.php】单例模式
    【PHP设计模式 04_GongChang.php】 工厂方法
    【PHP设计模式 03_JianDanGongChang.php】 简单工厂
    【PHP设计模式 02_JieKou.php】面向接口开发
    区块链学习-开始
    erc721-165学习
    cryptopunks的代码解释
  • 原文地址:https://www.cnblogs.com/shenben/p/6858509.html
Copyright © 2020-2023  润新知