bzoj1799[Ahoi2009]self 同类分布
[Ahoi2009]self 同类分布
Time Limit: 50 Sec Memory Limit: 64 MBSubmit: 1558 Solved: 687
[Submit][Status][Discuss]
Description
给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数。
Input
Output
Sample Input
10 19
Sample Output
3
HINT
【约束条件】1 ≤ a ≤ b ≤ 10^18
Source
题解:
数位dp,f[i][j][k][0/1]表示到第i位数位和为j,在模sum意义下的余数为k,是否卡上界的数的个数。
1 #include<cstring> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdio> 6 7 #define N 166 8 #define ll long long 9 using namespace std; 10 11 int mod,tot,cnt; 12 int a[25],mark[2][25][N][N]; 13 ll f[2][25][N][N]; 14 ll dp(int p,int d,int s,int v) 15 { 16 if (!d) return !s && !v; 17 if (mark[p][d][s][v]==tot) return f[p][d][s][v]; 18 mark[p][d][s][v]=tot; ll t=0; 19 int i,l=max(0,s-(d-1)*9),r=min((p)?9:a[d],s); 20 for (i=l; i<=r; i++) t+=dp(p|(i<a[d]),d-1,s-i,(v*10+i)%mod); 21 return f[p][d][s][v]=t; 22 } 23 ll solve(ll x) 24 { 25 ll t=0; 26 for (cnt=0; x; x/=10) a[++cnt]=x%10; 27 for (mod=1; mod<=cnt*9; mod++) 28 { 29 tot++; 30 t+=dp(0,cnt,mod,0); 31 } 32 return t; 33 } 34 int main() 35 { 36 ll x,y; scanf("%lld%lld",&x,&y); 37 printf("%lld\n",solve(y)-solve(x-1)); 38 }