http://www.lightoj.com/volume_showproblem.php?problem=1068

类型:数位DP

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 #define ll unsigned int
 6 ll dp[83][11][83][83],md[12]={1};
 7 void init()
 8 {
 9     memset(dp,0,sizeof(dp));
10     for(int i=1;i<11;i++)
11     md[i]=10*md[i-1];
12     for(int k=1;k<83;k++)
13         for(int i=0;i<10;i++)
14             dp[k][1][i%k][i%k]++;
15     for(int k=2;k<83;k++)
16     for(int i=2;i<11;i++)
17     for(int j=0;j<k;j++)
18     for(int l=0;l<k;l++)
19     for(int m=0;m<10;m++){
20         int tmp1=(m*md[i-1])%k;
21         int tmp2=m%k;
22         dp[k][i][j][l]+=dp[k][i-1][(k+j-tmp2)%k][(k+l-tmp1)%k];
23     }  
24 }
25 void print()
26 {
27     for(int k=2;k<5;k++)
28     for(int i=1;i<3;i++)
29     for(int j=0;j<k;j++)
30     for(int l=0;l<k;l++)
31     printf("k=%d i=%d j=%d l=%d ans=%d\n",k,i,j,l,dp[k][i][j][l]);
32 }
33 ll solve(ll x,ll k)
34 {
35     ll dig[15],cnt=0,ans=0;
36     while(x){
37         dig[++cnt]=x%10;
38         x/=10;
39     }
40     ll sum=0,mul=0;
41     for(int i=cnt;i>1;i--){
42         for(int j=0;j<dig[i];j++){
43             ll tmp1=(sum+j)%k;
44             ll tmp2=(mul+j*md[i-1])%k;
45             ans+=dp[k][i-1][(k-tmp1)%k][(k-tmp2)%k];
46         }
47        
48         sum=(sum+dig[i])%k;
49         mul=(mul+dig[i]*md[i-1])%k;
50     }
51     for(int i=0;i<dig[1];i++)
52         if((mul+i)%k==0&&(sum+i)%k==0)
53             ans++;
54     return ans;
55 }
56 int main()
57 {
58     init();
59     int t,cas=1;
60     scanf("%d",&t);
61     while(t--){
62         ll l,r,k;
63         scanf("%d%d%d",&l,&r,&k);
64         printf("Case %d: ",cas++);
65         if(k==1)
66         printf("%d\n",r-l+1);
67         else if(k>82)
68         printf("0\n");
69         else
70         printf("%u\n",solve(r+1,k)-solve(l,k));
71     }
72     return 0;
73 }
AC Code