1 /*
2 题意:求 1...n, n<10^12中满足x%sum(x)==0的数的个数,sum(x)为x的各个位数的和
3 题解:数位DP
4 时间:2018.08.03
5 */
6
7 #include <bits/stdc++.h>
8 using namespace std;
9
10 typedef long long LL;
11 const int MAXN = 100005;
12 const LL MOD7 = 1e9+7;
13
14 LL dp[15][125][125][125];
15
16 // 位数, 和, 模, 余数, dp[i][s][R][r]当前位数是i, 和为s,对R取模余数是r的个数
17 // 每次枚举最后一位, 有 dp[i+1][s+j][R][(r*10+j)%R] += dp[i][s][R][r];
18
19 void init()
20 {
21 memset(dp,0LL,sizeof(dp));
22 for (int i=1;i<=9*12;++i) dp[0][0][i][0]=1;
23 for (int i=0;i<=12;++i)
24 {
25 for (int s=0;s<=9*12;++s)
26 {
27 for (int R=1;R<=9*12;++R)
28 {
29 for (int r=0;r<R;++r)
30 {
31 if (dp[i][s][R][r])
32 {
33 for (int j=0;j<=9;++j)
34 {
35 dp[i+1][s+j][R][(r*10+j)%R]+=dp[i][s][R][r];
36 }
37 }
38 }
39 }
40 }
41 }
42 }
43
44 int b[15];
45 int m;
46 LL n;
47
48 LL get_b(LL n)
49 {
50 LL t=1;
51 m=0;
52 while (n)
53 {
54 b[m++]=n%10;
55 n/=10;
56 t*=10;
57 }
58 reverse(b,b+m);
59 return t/10;
60 }
61
62
63 // 统计<n的满足条件的方案数。
64 // 每次从高位枚举n=a1a2a3...am的一位,例如a2=3 枚举j=0, 1, 2, 3, 然后统计a1固定时,第二位为j时,枚举剩下位置的和为s
65 // 对应的结果就是就是,长度为 len = m-2, s,
66 // 模数 R = 前面固定的和 + j + s
67 // 需要的余数是 r = (R-(前面固定位置的值+ j对应的值) % R) %R
68 // 也就是 dp[len][s][sum+j+s][(R-(value+j*q)%R)%R] , sum是前面固定位置的总和,value为其对应的值,q=10^len,当前位的权重。
69
70 LL solve(LL n)
71 {
72 LL q = get_b(n);
73 // for (int i=0;i<m;++i) cout<<b[i]<<" ";cout<<endl;
74 // cout<<q<<endl;
75 LL ans=0;
76 int sum=0;
77 LL value=0;
78 for (int i=0;i<m;++i)
79 {
80 int len= m-i-1;
81 for (int j=0;j<b[i];++j)
82 {
83 for (int s=0;s<=9*len;++s)
84 {
85 int R = sum+j+s;
86 if (R>0)
87 {
88 int r=(int)(R-(value+j*q)%R) % R;
89 ans+=dp[len][s][R][r];
90 }
91 }
92 }
93 value += q*b[i];
94 q/=10;
95 sum+=b[i];
96 }
97 int tmp=0;
98 for (int i=0;i<m;++i) tmp+=b[i];
99 ans+=(n%tmp==0);
100 return ans;
101 }
102
103 int main()
104 {
105 #ifndef ONLINE_JUDGE
106 // freopen("test.txt","r",stdin);
107 #endif // ONLINE_JUDGE
108 init();
109 scanf("%lld",&n);
110 printf("%lld\n",solve(n));
111 return 0;
112 }