BZOJ 2757: [SCOI2012]Blinker的仰慕者 数位DP

来源:互联网 发布:centos7查看端口占用 编辑:程序博客网 时间:2024/04/27 23:25

好繁琐,因为难处理,分为k==0和k!=0两类处理。

代码很丑。。。手残伤不起。。。

//#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<cmath>#include<cctype>#include<string>#include<algorithm>#include<iostream>#include<ctime>#include<map>#include<set>using namespace std;#define MP(x,y) make_pair((x),(y))#define PB(x) push_back(x)typedef long long LL;//typedef unsigned __int64 ULL;/* ****************** */const int INF=100011122;const double INFF=1e100;const double eps=1e-8;const int mod=20120427;const int NN=1005;const int MM=1000010;/* ****************** *///保证没有0int sum[19][55][37][19][19];int dp[19][55][37][19][19];LL pp10[20];int a[20];int jian[10][4];//用于计算k==0LL dp0[20][3];LL sum0[20][3];/*0:有中间01:只有前导02:无0*/void INC(int &a,LL b){    b%=mod;    a+=b;    if(a>=mod)        a-=mod;}void init(int n){    int i,j1,j2,j3,j4;    LL t,tt;    memset(sum,0,sizeof(sum));    memset(dp,0,sizeof(dp));    memset(dp0,0,sizeof(dp0));    memset(sum0,0,sizeof(sum0));    //0    jian[0][0]=0;    jian[0][1]=0;    jian[0][2]=0;    jian[0][3]=0;    //1    jian[1][0]=0;    jian[1][1]=0;    jian[1][2]=0;    jian[1][3]=0;    //2    jian[2][0]=1;    jian[2][1]=0;    jian[2][2]=0;    jian[2][3]=0;    //3    jian[3][0]=0;    jian[3][1]=1;    jian[3][2]=0;    jian[3][3]=0;    //4    jian[4][0]=2;    jian[4][1]=0;    jian[4][2]=0;    jian[4][3]=0;    //5    jian[5][0]=0;    jian[5][1]=0;    jian[5][2]=1;    jian[5][3]=0;    //6    jian[6][0]=1;    jian[6][1]=1;    jian[6][2]=0;    jian[6][3]=0;    //7    jian[7][0]=0;    jian[7][1]=0;    jian[7][2]=0;    jian[7][3]=1;    //8    jian[8][0]=3;    jian[8][1]=0;    jian[8][2]=0;    jian[8][3]=0;    //9    jian[9][0]=0;    jian[9][1]=2;    jian[9][2]=0;    jian[9][3]=0;    pp10[0]=1;    for(i=1;i<=19;i++)    {        pp10[i]=pp10[i-1]*10%mod;    }    dp0[0][2]=1;    for(i=0;i<n;i++)    {        if(dp0[i][0] || sum0[i][0])        {            dp0[i+1][0]+=dp0[i][0]*10;            dp0[i+1][0]%=mod;            sum0[i+1][0]+=sum0[i][0]*10;            t=(LL)(dp0[i][0]*45%mod)*pp10[i];            t%=mod;            sum0[i+1][0]+=t;            sum0[i+1][0]%=mod;        }        if(dp0[i][1] || sum0[i][1])        {            //0            dp0[i+1][1]+=dp0[i][1];            dp0[i+1][1]%=mod;            sum0[i+1][1]+=sum0[i][1];            sum0[i+1][1]%=mod;            //!0            dp0[i+1][0]+=dp0[i][1]*9;            dp0[i+1][0]%=mod;            sum0[i+1][0]+=sum0[i][1]*9;            t=(LL)(dp0[i][1]*45%mod)*pp10[i];            t%=mod;            sum0[i+1][0]+=t;            sum0[i+1][0]%=mod;        }        if(dp0[i][2] || sum0[i][2])        {            //0            dp0[i+1][1]+=dp0[i][2];            dp0[i+1][1]%=mod;            sum0[i+1][1]+=sum0[i][2];            sum0[i+1][1]%=mod;            //!0            dp0[i+1][2]+=dp0[i][2]*9;            dp0[i+1][2]%=mod;            sum0[i+1][2]+=sum0[i][2]*9;            t=(LL)(dp0[i][2]*45%mod)*pp10[i];            t%=mod;            sum0[i+1][2]+=t;            sum0[i+1][2]%=mod;        }    }    dp[0][0][0][0][0]=1;    for(i=0;i<n;i++)        for(j1=0;j1<=54;j1++)            for(j2=0;j2<=36;j2++)                for(j3=0;j3<=18;j3++)                    for(j4=0;j4<=18;j4++)                    {                        if(dp[i][j1][j2][j3][j4] || sum[i][j1][j2][j3][j4])                        {                            t=dp[i][j1][j2][j3][j4];                            tt=sum[i][j1][j2][j3][j4];                            //1                            dp[i+1][j1][j2][j3][j4]+=t;                            dp[i+1][j1][j2][j3][j4]%=mod;                            INC(sum[i+1][j1][j2][j3][j4],tt);                            INC(sum[i+1][j1][j2][j3][j4],t*pp10[i]);                            //2                            dp[i+1][j1+1][j2][j3][j4]+=t;                            dp[i+1][j1+1][j2][j3][j4]%=mod;                            INC(sum[i+1][j1+1][j2][j3][j4],tt);                            INC(sum[i+1][j1+1][j2][j3][j4],t*pp10[i]*2);                            //3                            dp[i+1][j1][j2+1][j3][j4]+=t;                            dp[i+1][j1][j2+1][j3][j4]%=mod;                            INC(sum[i+1][j1][j2+1][j3][j4],tt);                            INC(sum[i+1][j1][j2+1][j3][j4],t*pp10[i]*3);                            //4                            dp[i+1][j1+2][j2][j3][j4]+=t;                            dp[i+1][j1+2][j2][j3][j4]%=mod;                            INC(sum[i+1][j1+2][j2][j3][j4],tt);                            INC(sum[i+1][j1+2][j2][j3][j4],t*pp10[i]*4);                            //5                            dp[i+1][j1][j2][j3+1][j4]+=t;                            dp[i+1][j1][j2][j3+1][j4]%=mod;                            INC(sum[i+1][j1][j2][j3+1][j4],tt);                            INC(sum[i+1][j1][j2][j3+1][j4],t*pp10[i]*5);                            //6                            dp[i+1][j1+1][j2+1][j3][j4]+=t;                            dp[i+1][j1+1][j2+1][j3][j4]%=mod;                            INC(sum[i+1][j1+1][j2+1][j3][j4],tt);                            INC(sum[i+1][j1+1][j2+1][j3][j4],t*pp10[i]*6);                            //7                            dp[i+1][j1][j2][j3][j4+1]+=t;                            dp[i+1][j1][j2][j3][j4+1]%=mod;                            INC(sum[i+1][j1][j2][j3][j4+1],tt);                            INC(sum[i+1][j1][j2][j3][j4+1],t*pp10[i]*7);                            //8                            dp[i+1][j1+3][j2][j3][j4]+=t;                            dp[i+1][j1+3][j2][j3][j4]%=mod;                            INC(sum[i+1][j1+3][j2][j3][j4],tt);                            INC(sum[i+1][j1+3][j2][j3][j4],t*pp10[i]*8);                            //9                            dp[i+1][j1][j2+2][j3][j4]+=t;                            dp[i+1][j1][j2+2][j3][j4]%=mod;                            INC(sum[i+1][j1][j2+2][j3][j4],tt);                            INC(sum[i+1][j1][j2+2][j3][j4],t*pp10[i]*9);                        }                    }    dp[0][0][0][0][0]=0;    for(i=2;i<=n;i++)        for(j1=0;j1<=54;j1++)            for(j2=0;j2<=36;j2++)                for(j3=0;j3<=18;j3++)                    for(j4=0;j4<=18;j4++)                    {                        dp[i][j1][j2][j3][j4]+=dp[i-1][j1][j2][j3][j4];                        if(dp[i][j1][j2][j3][j4]>=mod)                            dp[i][j1][j2][j3][j4]-=mod;                        sum[i][j1][j2][j3][j4]+=sum[i-1][j1][j2][j3][j4];                        if(sum[i][j1][j2][j3][j4]>=mod)                            sum[i][j1][j2][j3][j4]-=mod;                    }}LL dfs_sum(int pos,int n1,int n2,int n3,int n4,LL t_sum,bool fg,bool allzero){    if(pos==0)    {        if(n1==0 && n2==0 && n3==0 && n4==0)            return t_sum;        return 0;    }    if(!fg)    {        if(allzero)        {            return sum[pos][n1][n2][n3][n4];        }        else        {            LL temp=sum[pos][n1][n2][n3][n4]-sum[pos-1][n1][n2][n3][n4];            if(temp<0)temp+=mod;            LL temp1=dp[pos][n1][n2][n3][n4]-dp[pos-1][n1][n2][n3][n4];            if(temp1<0)temp1+=mod;            temp+=t_sum*temp1;            temp%=mod;            return temp;        }    }    int i;    LL ans=0;    if(allzero)        i=0;    else        i=1;    for(;i<=a[pos];i++)    {        int m1=n1-jian[i][0];        int m2=n2-jian[i][1];        int m3=n3-jian[i][2];        int m4=n4-jian[i][3];        if(m1>=0 && m2>=0 && m3>=0 && m4>=0)        {            ans+=dfs_sum(pos-1,m1,m2,m3,m4,(t_sum+i*pp10[pos-1])%mod,i==a[pos],allzero&&(i==0));            if(ans>=mod)                ans-=mod;        }    }    return ans;}LL calc(LL x,int n1,int n2,int n3,int n4){    int tol=0;    do    {        a[++tol]=x%10;        x/=10;    }while(x);    return dfs_sum(tol,n1,n2,n3,n4,0,1,1);}LL solve(LL st,LL en,int n1,int n2,int n3,int n4){    LL ans=calc(en,n1,n2,n3,n4)-calc(st-1,n1,n2,n3,n4);    if(ans<0)ans+=mod;    return ans;}LL dfs_zero_sum(int pos,LL t_sum,bool ok,bool fg,bool allzero){    if(pos==0)    {        if(ok)return t_sum;        return 0;    }    if(!fg)    {        if(ok)        {            LL temp=pp10[pos-1]*(pp10[pos]-1)*5;            temp%=mod;            if(temp<0)temp+=mod;            temp+=t_sum*pp10[pos];            temp%=mod;            return temp;        }        else        {            LL temp=sum0[pos][0];            temp+=t_sum*dp0[pos][0];            temp%=mod;            if(!allzero)            {                temp+=sum0[pos][1];                temp%=mod;                temp+=t_sum*dp0[pos][1]%mod;                temp%=mod;            }            return temp;        }    }    int i;    LL ans=0;    bool ok1;    for(i=0;i<=a[pos];i++)    {        ok1=ok;        if(i==0 && !allzero)            ok1=true;        ans+=dfs_zero_sum(pos-1,(t_sum+i*pp10[pos-1])%mod,ok1,i==a[pos],allzero&&(i==0));        if(ans>=mod)            ans-=mod;    }    return ans;}LL calc_zero(LL x){    int tol=0;    do    {        a[++tol]=x%10;        x/=10;    }while(x);    return dfs_zero_sum(tol,0,0,1,1);}void solve_zero(LL st,LL en){    LL ans=calc_zero(en)-calc_zero(st-1);    if(ans<0)ans+=mod;    printf("%lld\n",ans);}int main(){    init(18);    int cas;    int n1,n2,n3,n4;    LL st,en,k,ans;    scanf("%d",&cas);    while(cas--)    {        scanf("%lld%lld%lld",&st,&en,&k);        if(k==0)        {            solve_zero(st,en);            continue;        }        n1=n2=n3=n4=0;        while(k%2==0)        {            n1++;            k/=2;        }        while(k%3==0)        {            n2++;            k/=3;        }        while(k%5==0)        {            n3++;            k/=5;        }        while(k%7==0)        {            n4++;            k/=7;        }        if(k>1 || n1>54 || n2>36 || n3>18 || n4>18)        {            ans=0;        }        else        {            ans=solve(st,en,n1,n2,n3,n4);        }        printf("%lld\n",ans);    }    return 0;}


0 0