Codeforces 10C

C. Digital Root
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Not long ago Billy came across such a problem, where there were given three natural numbers AB and C from the range [1, N], and it was asked to check whether the equation AB = C is correct. Recently Billy studied the concept of a digital root of a number. We should remind you that a digital root d(x) of the number x is the sum s(x) of all the digits of this number, if s(x) ≤ 9, otherwise it is d(s(x)). For example, a digital root of the number 6543 is calculated as follows: d(6543) = d(6 + 5 + 4 + 3) = d(18) = 9. Billy has counted that the digital root of a product of numbers is equal to the digital root of the product of the factors' digital roots, i.e. d(xy) = d(d(x)d(y)). And the following solution to the problem came to his mind: to calculate the digital roots and check if this condition is met. However, Billy has doubts that this condition is sufficient. That's why he asks you to find out the amount of test examples for the given problem such that the algorithm proposed by Billy makes mistakes.

Input

The first line contains the only number N (1 ≤ N ≤ 106).

Output

Output one number — the amount of required AB and C from the range [1, N].

Examples
input
4
output
2
input
5
output
6
Note

For the first sample the required triples are (3, 4, 3) and (4, 3, 3).

题意:在闭区间[1,n]里找出所有的数字组合(a,b,c),且满足a×b≠c且d(d(a)×d(b))=d(c)。

题解:数论。

刚看到这题,很显然能想到最朴素的做法是O(n2)暴力枚举判断,显然是TLE的。

对于此题我们可以先找出函数d(x)的含义。总结规律不难发现,d(x)即使将x%9后得到的余数,当然我们需要把9看成0才能得到这个结论,但这样转化后并不影响解题。

于是我们可以先算出所有在闭区间[1,n]内满足d(d(a)×d(b))=d(c)的数字组合。然后我们只要减去该组合中满足a×b=c的数字组合就行了。

仔细分析可以得出凡是满足a×b=c的,必有d(d(a)×d(b))=d(c),即前者为后者的子集。则直接减去所有a×b=c的组合就行了。

减去a×b=c的组合进行该方法用O(n)复杂度,从1到n扫一遍,减去n/i向下取整的值就能无重复无遗漏地减掉这些子集。

统计d(d(a)×d(b))=d(c)的数字组合时,先在上一步O(n)处理的时候算出这个数%9的值,然后扔到相应的桶里,之后只需O(9×9)枚举即可。

详细细节参考代码。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,a[10];
 4 long long ans;
 5 int main()
 6 {
 7     scanf("%d",&n);
 8     for (int i=1;i<=n;++i)
 9     ++a[i%9],ans-=n/i;
10     for (int i=0;i<9;++i)
11     for (int j=0;j<9;++j)
12     ans+=(long long)a[i]*a[j]*a[i*j%9];
13     printf("%lld
",ans);
14     return 0;
15 }
View Code
原文地址:https://www.cnblogs.com/zk1431043937/p/7725560.html