zoukankan      html  css  js  c++  java
  • bzoj 3679: 数字之积

    注意到每个数位的质因子只会有2,3,5,7四种,所以分开统计,数位dp

    此题卡空间,最好是写成循环,用滚动数组,我这里是卡了好久才过去的

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 typedef long long LL;
     6 LL dp[55][37][19][19][19];
     7 LL d2[]={0,0,1,0,2,0,1,0,3,0};
     8 LL d3[]={0,0,0,1,0,0,1,0,0,2};
     9 LL d5[]={0,0,0,0,0,1,0,0,0,0};
    10 LL d7[]={0,0,0,0,0,0,0,1,0,0};
    11 LL g[30],glen;
    12 LL dfs(LL pos,LL a,LL b,LL c,LL d,bool limit,bool pre0)
    13 {
    14     if(a<0||b<0||c<0||d<0)  return 0;
    15     if(!pos)    return !pre0&&a==0&&b==0&&c==0&&d==0;
    16     if(!limit&&!pre0&&dp[pos][a][b][c][d]!=-1)
    17         return dp[pos][a][b][c][d];
    18     LL ed=limit?g[pos]:9,res=0,i;
    19     for(i=1;i<=ed;i++)
    20         res+=dfs(pos-1,a-d2[i],b-d3[i],c-d5[i],d-d7[i],limit&&i==g[pos],pre0&&i==0);
    21     return limit||pre0?res:dp[pos][a][b][c][d]=res;
    22 }
    23 LL get(LL a,LL b,LL c,LL d)
    24 {
    25     LL ans=0,i;
    26     for(i=1;i<=glen;i++) ans+=dfs(i,a,b,c,d,i==glen,1);
    27     return ans;
    28 }
    29 LL n,L,R;
    30 LL pw2[70],pw3[70],pw5[70],pw7[70];
    31 bool judge(LL a,LL b,LL c,LL d)
    32 {
    33     LL ans=1;
    34     if(pw2[a]==-1||pw3[b]==-1||pw5[c]==-1||pw7[d]==-1)  return 0;
    35     ans*=pw2[a];if(ans>n)    return 0;
    36     ans*=pw3[b];if(ans>n)    return 0;
    37     ans*=pw5[c];if(ans>n)    return 0;
    38     ans*=pw7[d];if(ans>n)    return 0;
    39     return 1;
    40 }
    41 LL ans;
    42 int main()
    43 {
    44     LL i,j,k,l;
    45     memset(dp,-1,sizeof(dp));
    46     scanf("%lld%lld%lld",&n,&L,&R);L--;R--;
    47     pw2[0]=pw3[0]=pw5[0]=pw7[0]=1;
    48     for(i=1;i<=60;i++)
    49     {
    50         if(pw2[i-1]==-1)    pw2[i]=-1;
    51         else    pw2[i]=pw2[i-1]*2;
    52         if(pw3[i-1]==-1)    pw3[i]=-1;
    53         else    pw3[i]=pw3[i-1]*3;
    54         if(pw5[i-1]==-1)    pw5[i]=-1;
    55         else    pw5[i]=pw5[i-1]*5;
    56         if(pw7[i-1]==-1)    pw7[i]=-1;
    57         else    pw7[i]=pw7[i-1]*7;
    58         if(pw2[i]>n) pw2[i]=-1;
    59         if(pw3[i]>n) pw3[i]=-1;
    60         if(pw5[i]>n) pw5[i]=-1;
    61         if(pw7[i]>n) pw7[i]=-1;
    62     }
    63     for(glen=0;R;R/=10) g[++glen]=R%10;
    64     for(i=0;i<=55;i++)
    65         for(j=0;j<=37;j++)
    66             for(k=0;k<=19;k++)
    67                 for(l=0;l<=19;l++)
    68                 {
    69                     if(!judge(i,j,k,l)) continue;
    70                     ans+=get(i,j,k,l);
    71                 }
    72     for(glen=0;L;L/=10) g[++glen]=L%10;
    73     for(i=0;i<=55;i++)
    74         for(j=0;j<=37;j++)
    75             for(k=0;k<=19;k++)
    76                 for(l=0;l<=19;l++)
    77                 {
    78                     if(!judge(i,j,k,l)) continue;
    79                     ans-=get(i,j,k,l);
    80                 }
    81     printf("%lld",ans);
    82     return 0;
    83 }
    View Code

    20180928

    用循环重新写了一遍

    错误记录:没有判138行"!has0[p+1]",无限WA

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 using namespace std;
      6 #define fi first
      7 #define se second
      8 #define mp make_pair
      9 #define pb push_back
     10 typedef long long ll;
     11 typedef unsigned long long ull;
     12 typedef pair<int,int> pii;
     13 ll g[22];
     14 namespace s1
     15 {
     16  
     17 ll an[22][2][2];//an[i位][是否含0(含前导0)][第i位是否为(前导)0]
     18 void pre()
     19 {
     20     ll i;
     21     an[0][0][1]=1;
     22     for(i=1;i<=19;i++)
     23     {
     24         an[i][1][0]=9*(an[i-1][1][0]+an[i-1][1][1]);
     25         an[i][1][1]=an[i-1][1][0]+an[i-1][1][1]+an[i-1][0][0]+an[i-1][0][1];
     26         an[i][0][0]=9*(an[i-1][0][0]+an[i-1][0][1]);
     27         an[i][0][1]=0;
     28     }
     29 }
     30 ll calc()//[1,g)之间有多少个数数位中有0
     31 {
     32     ll i,ans=0;
     33     for(i=1;i<g[0];i++)//g[0]位取0
     34     {
     35         ans+=an[i][1][0];
     36     }
     37     if(g[g[0]]!=0)//g[0]位取1~(g[g[0]]-1)
     38         ans+=(g[g[0]]-1)*(an[g[0]-1][1][0]+an[g[0]-1][1][1]);
     39     bool ok=0;
     40     for(i=g[0]-1;i>=1;i--)//i位之前与原数相同,i位小于原数,i位以后任意取
     41     {
     42         if(ok)  ans+=g[i]*(an[i-1][0][0]+an[i-1][0][1]+an[i-1][1][0]+an[i-1][1][1]);
     43         else if(g[i]!=0)
     44         {
     45             ans+=(g[i]-1)*(an[i-1][1][0]+an[i-1][1][1]);//当前位取1~g[i]
     46             ans+=an[i-1][0][0]+an[i-1][0][1]+an[i-1][1][0]+an[i-1][1][1];//当前位取0
     47         }
     48         ok|=(g[i]==0);
     49     }
     50     //if(ok)    ans++;
     51     return ans;
     52 }
     53  
     54  
     55 }
     56 /*
     57 xx2:;
     58 int main()
     59 {
     60     s1::pre();
     61     while(1)
     62     {
     63         ll t;scanf("%lld",&t);
     64         for(g[0]=0;t;t/=10) g[++g[0]]=t%10;
     65         printf("%lld
    ",s1::calc());
     66     }
     67     return 0;
     68 }
     69 */
     70 ll d2[]={0,0,1,0,2,0,1,0,3,0};
     71 ll d3[]={0,0,0,1,0,0,1,0,0,2};
     72 ll d5[]={0,0,0,0,0,1,0,0,0,0};
     73 ll d7[]={0,0,0,0,0,0,0,1,0,0};
     74 ll s2[22],s3[22],s5[22],s7[22];
     75 bool has0[22];
     76 ll an[2][56][38][20][20];
     77 //an[i位][p2][p3][p5][p7]
     78 ll calc(ll R,ll R1)//数[0,R],数位积[0,R1]
     79 {
     80     if(R<0||R1<0) return 0;
     81     if(R==0)    return 1;
     82     ll ans=1;//数0
     83     R++;
     84     for(g[0]=0;R;R/=10) g[++g[0]]=R%10;
     85     ans+=s1::calc();//数位积0
     86     ll p,i,j,k,l,nn,pw1,pw2,pw3,pw4;
     87     /*
     88     for(t=1,i=1;i<=18;t=t*10+1,i++)//数位积1
     89         if(t<=R)
     90             ans++;
     91     */
     92     //此处之后只需要统计数[1,R),数位积[1,R1]
     93     //处理[1,R)
     94     s2[g[0]+1]=s3[g[0]+1]=s5[g[0]+1]=s7[g[0]+1]=0;has0[g[0]+1]=0;
     95     for(i=g[0];i>=1;i--)
     96     {
     97         s2[i]=s2[i+1]+d2[g[i]];
     98         s3[i]=s3[i+1]+d3[g[i]];
     99         s5[i]=s5[i+1]+d5[g[i]];
    100         s7[i]=s7[i+1]+d7[g[i]];
    101         has0[i]=has0[i+1]||(g[i]==0);
    102     }
    103     ll lst=1,now=0;
    104     memset(an[now],0,sizeof(an[now]));
    105     an[now][0][0][0][0]=1;
    106     for(p=1;p<=g[0];p++)
    107     {
    108         swap(lst,now);
    109         memset(an[now],0,sizeof(an[now]));
    110         for(i=0,pw1=1;pw1<=R1&&i<56;i++,pw1*=2)
    111             for(j=0,pw2=pw1;pw2<=R1&&j<38;j++,pw2*=3)
    112                 for(k=0,pw3=pw2;pw3<=R1&&k<20;k++,pw3*=5)
    113                     for(l=0,pw4=pw3;pw4<=R1&&l<20;l++,pw4*=7)
    114                     {
    115                         for(nn=1;nn<=9;nn++)
    116                             if(i>=d2[nn]&&j>=d3[nn]&&k>=d5[nn]&&l>=d7[nn])
    117                                 an[now][i][j][k][l]+=an[lst][i-d2[nn]][j-d3[nn]][k-d5[nn]][l-d7[nn]];
    118                     }
    119         if(p<g[0])
    120         {
    121             for(i=0,pw1=1;pw1<=R1&&i<56;i++,pw1*=2)
    122                 for(j=0,pw2=pw1;pw2<=R1&&j<38;j++,pw2*=3)
    123  
    124                     for(k=0,pw3=pw2;pw3<=R1&&k<20;k++,pw3*=5)
    125                         for(l=0,pw4=pw3;pw4<=R1&&l<20;l++,pw4*=7)
    126                             ans+=an[now][i][j][k][l];
    127         }
    128         if(p==g[0])
    129         {
    130             for(i=0,pw1=1;pw1<=R1&&i<56;i++,pw1*=2)
    131                 for(j=0,pw2=pw1;pw2<=R1&&j<38;j++,pw2*=3)
    132                     for(k=0,pw3=pw2;pw3<=R1&&k<20;k++,pw3*=5)
    133                         for(l=0,pw4=pw3;pw4<=R1&&l<20;l++,pw4*=7)
    134                             for(nn=1;nn<g[p];nn++)
    135                                 if(i>=d2[nn]&&j>=d3[nn]&&k>=d5[nn]&&l>=d7[nn])
    136                                     ans+=an[lst][i-d2[nn]][j-d3[nn]][k-d5[nn]][l-d7[nn]];
    137         }
    138         if(p<g[0]&&!has0[p+1])
    139         {
    140             for(i=0,pw1=1;pw1<=R1&&i<56;i++,pw1*=2)
    141                 for(j=0,pw2=pw1;pw2<=R1&&j<38;j++,pw2*=3)
    142                     for(k=0,pw3=pw2;pw3<=R1&&k<20;k++,pw3*=5)
    143                         for(l=0,pw4=pw3;pw4<=R1&&l<20;l++,pw4*=7)
    144                             for(nn=1;nn<g[p];nn++)
    145                                 if(i>=s2[p+1]+d2[nn]&&j>=s3[p+1]+d3[nn]
    146                                         &&k>=s5[p+1]+d5[nn]&&l>=s7[p+1]+d7[nn])
    147                                     ans+=an[lst][i-s2[p+1]-d2[nn]][j-s3[p+1]-d3[nn]]
    148                                         [k-s5[p+1]-d5[nn]][l-s7[p+1]-d7[nn]];
    149         }
    150     }
    151     return ans;
    152 }
    153 int main()
    154 {
    155     s1::pre();
    156    /* 
    157     while(1)
    158     {
    159         ll t1,t2;
    160         scanf("%lld%lld",&t1,&t2);
    161         printf("%lld
    ",calc(t1,t2));
    162     }*/
    163     ll L,R,L1,R1;
    164     //scanf("%lld%lld%lld%lld",&L,&R,&L1,&R1);
    165     scanf("%lld%lld%lld",&R1,&L,&R);
    166     R--;L1=1;
    167     printf("%lld",calc(R,R1)-calc(R,L1-1)-calc(L-1,R1)+calc(L-1,L1-1));
    168     return 0;
    169 }
    View Code

    双倍经验:https://www.nowcoder.com/acm/contest/172/B

  • 相关阅读:
    第二章.md
    第四章.md
    第一章.md
    第九章.md
    png简析.md
    第五章.md
    好看的粒子效果
    缓动 减速运动
    收集的小效果
    粒子效果2
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8884703.html
Copyright © 2011-2022 走看看