zoukankan      html  css  js  c++  java
  • bzoj 3530 [Sdoi2014]数数

    传送门

    de了整整三个小时bug.

    一直担心我的数位dp,然而并没错。

    AC自动机各种毛病,fail怎么都不对,DE到怀疑人生,

    最后发现我tmd用了一个栈来get_fail;

    一直用stl突然心血来潮要手写一个队列,结果我tmd写成了一个栈。。

    今晚真的是怀疑人生,

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<ctime>
    const int N=1507; 
    const int mod=1e9+7;
    typedef long long LL;
    using namespace std;
    int m,lim[N],s[N];
    LL dp[N][N][3],ans;
    
    void read(int a[]) {
        char ch=getchar(); 
        while(ch<'0'||ch>'9') ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) a[++a[0]]=ch-'0';
    }
    
    int rt,tot,ch[N][10],is[N],fail[N];
    void insert() {
        int x=rt;
        for(int i=1;i<=s[0];i++) {
            int c=s[i];
            if(!ch[x][c]) ch[x][c]=++tot;
            x=ch[x][c];
        }
        is[x]=1;
    }
    
    queue<int>que;
    void get_fail() {
        que.push(rt);
        while(!que.empty()) {
            int x=que.front();
            que.pop();
            for(int i=0;i<10;i++) if(ch[x][i]) {
                int y=ch[x][i];
                if(x==rt) fail[y]=rt;
                else {
                    int z=fail[x];
                    for(;!ch[z][i]&&z;z=fail[z]);
                    if(ch[z][i]) fail[y]=ch[z][i];
                    else fail[y]=rt;
                    if(is[fail[y]]) is[y]=1;
                }
                que.push(ch[x][i]);
            }
        }
    }
    
    void pls(LL &a,LL b) { a+=b; if(a>=mod) a-=mod;}
    
    void solve() {
        dp[0][0][1]=1;
        dp[0][0][2]=1;
        for(int i=1;i<=lim[0];i++) 
            for(int j=0;j<=tot;j++) if(!is[j]&&(dp[i-1][j][0]||dp[i-1][j][1]||dp[i-1][j][2])) {
                for(int k=(i==1);k<10;k++) {
                    int y=ch[j][k];
                    if(!y) {
                        int tp=fail[j];
                        while(!ch[tp][k]&&tp) tp=fail[tp];
                        if(ch[tp][k]) y=ch[tp][k]; else y=rt;
                    }
                    if(is[y]) continue;
                    if(i==3&&y==0) {
                        int cnm=0;
                    }
                    pls(dp[i][y][2],dp[i-1][j][2]);
                    pls(dp[i][y][0],dp[i-1][j][0]);
                    if(k<lim[i]) pls(dp[i][y][0],dp[i-1][j][1]);
                    if(k==lim[i]) pls(dp[i][y][1],dp[i-1][j][1]);
                }
            }
        for(int i=1;i<=lim[0];i++) {
            int debug=1;
            for(int j=0;j<=tot;j++) if(!is[j]) {
                if(i<lim[0]) pls(ans,dp[i][j][2]);
                else {
                    pls(ans,dp[i][j][0]);
                    pls(ans,dp[i][j][1]);
                }
            }
        }
    }
    
    int main() {
        read(lim);
        cin>>m;
        for(int i=1;i<=m;i++) {
            s[0]=0; read(s);
            insert();
        }
        get_fail();
        solve();
        printf("%lld
    ",ans);
        return 0;
    }
    /*
    7391
    3
    21
    1923
    98
    */ 
    View Code
  • 相关阅读:
    centos7安装KVM
    keepalived高可用
    Jenkins-Pipeline 流水线发布部署项目
    centos7部署jenkins
    版本控制gitlab
    c语言寻找3000以内亲密数对
    c语言寻找1000以内的完全数
    c语言分解因式
    c语言判断给定日期是当年的第几天
    c语言计算程序运行时间
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8319161.html
Copyright © 2011-2022 走看看