[BZOJ3679]数字之积 数位DP
2017-10-17 19:13
309 查看
首先还是ANS[L,R)=ANS[1,R-1]-ANS[1,L-1]。
f[i][j][0/1]表示从高到低填到第i位,积为j的个数。
不过j太大了,但我们发现数字之积分解质因数只可能有2,3,5,7。于是设计状态f[i][c2][c3][c5][c7][0/1],c2,c3,c5,c7表示它们的次数。这样复杂度为O(log2N*log3N*log5N*log7N*18)。
不过hash的话状态数好像可以减到几千更优。
代码:
f[i][j][0/1]表示从高到低填到第i位,积为j的个数。
不过j太大了,但我们发现数字之积分解质因数只可能有2,3,5,7。于是设计状态f[i][c2][c3][c5][c7][0/1],c2,c3,c5,c7表示它们的次数。这样复杂度为O(log2N*log3N*log5N*log7N*18)。
不过hash的话状态数好像可以减到几千更优。
代码:
#include<iostream> #include<cstdio> #include<cstring> #define ll long long using namespace std; ll n,f[20][33][20][14][13][2],mi[20]; int z[10][4]={{0,0,0,0},{0,0,0,0},{1,0,0,0},{0,1,0,0},{2,0,0,0},{0,0,1,0},{1,1,0,0},{0,0,0,1},{3,0,0,0},{0,2,0,0}}; double cal(int d2,int d3,int d5,int d7) { double re=1; while(d2--) re*=2; while(d3--) re*=3; while(d5--) re*=5; while(d7--) re*=7; return re; } ll work(ll m) { memset(f,0,sizeof(f)); ll re=0; int bit=0; while(mi[bit]<=m) bit++; f[bit+1][0][0][0][0][1]=1; for(int v=bit;v>=1;v--) { int d=m/mi[v-1]%10; f[v][0][0][0][0][0]=1; for(int i=1;i<=9;i++) { int z2=z[i][0],z3=z[i][1],z5=z[i][2],z7=z[i][3]; if(i<d) { for(int c2=z2;c2<=32;c2++) for(int c3=z3;c3<=19;c3++) for(int c5=z5;c5<=13;c5++) for(int c7=z7;c7<=12;c7++) f[v][c2][c3][c5][c7][0]+=f[v+1][c2-z2][c3-z3][c5-z5][c7-z7][1]; } if(i==d) { for(int c2=z2;c2<=32;c2++) for(int c3=z3;c3<=19;c3++) for(int c5=z5;c5<=13;c5++) for(int c7=z7;c7<=12;c7++) f[v][c2][c3][c5][c7][1]+=f[v+1][c2-z2][c3-z3][c5-z5][c7-z7][1]; } for(int c2=z2;c2<=32;c2++) for(int c3=z3;c3<=19;c3++) for(int c5=z5;c5<=13;c5++) for(int c7=z7;c7<=12;c7++) f[v][c2][c3][c5][c7][0]+=f[v+1][c2-z2][c3-z3][c5-z5][c7-z7][0]; } } for(int c2=0;c2<=32;c2++) for(int c3=0;c3<=19;c3++) for(int c5=0;c5<=13;c5++) for(int c7=0;c7<=12;c7++) if(cal(c2,c3,c5,c7)<=n) re+=f[1][c2][c3][c5][c7][1]+f[1][c2][c3][c5][c7][0]; return re; } int main() { ll l,r; scanf("%lld%lld%lld",&n,&l,&r); mi[0]=1; for(int i=1;i<=18;i++) mi[i]=mi[i-1]*10; printf("%lld",work(r-1)-work(l-1)); return 0; }
相关文章推荐
- BZOJ 3679 数字之积 - 数位dp
- 【bzoj3679】 数字之积 数位dp
- BZOJ 3679 数字之积 (数位DP)
- [BZOJ3679][数位DP]数字之积
- [BZOJ]3679: 数字之积 数位DP
- 【数位DP】BZOJ3629数字之积
- BZOJ-1833 [ZJOI2010]count 数字计数 数位DP
- 【BZOJ1833】【ZJOI2010】count 数字计数 (数位DP)
- BZOJ1833 [ZJOI2010]count 数字计数 【数学 Or 数位dp】
- [BZOJ1833][ZJOI2010]count 数字计数(数位dp)
- bzoj 3780: 数字统计 (数位dp)
- BZOJ_1833_[ZJOI2010]count 数字计数_数位DP
- [BZOJ1833]ZJOI2010 数字计数|数位DP
- 【数位DP】BZOJ3629数字之积
- [BZOJ1833] [ZJOI2010]count 数字计数 && 数位DP
- 【codevs1359】【BZOJ1833】数字计数,进击的学弟与数位DP
- BZOJ 1799 self 同类分布(数位dp,区间各位数字和能整除原数的数字个数)
- 【BZOJ 1833】 [ZJOI2010]count 数字计数|数位DP
- BZOJ 1833 ZJOI2010 count 数字计数 数位DP
- 【BZOJ3679】数字之积 DFS+DP