bzoj1799[Ahoi2009]self 同类分布

[Ahoi2009]self 同类分布

Time Limit: 50 Sec  Memory Limit: 64 MB
Submit: 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 }

 

posted @ 2017-12-26 17:54  Kaiser-  阅读(359)  评论(0编辑  收藏  举报