题目链接:http://codeforces.com/problemset/problem/468/C
Little X has met the following problem recently.
Let's define f(x) as the sum of digits in decimal representation of number x (for example, f(1234) = 1 + 2 + 3 + 4). You are to calculate
Of course Little X has solved this problem quickly, has locked it, and then has tried to hack others. He has seen the following C++ code:
ans = solve(l, r) % a; if (ans <= 0) ans += a;
This code will fail only on the test with . You are given number a, help Little X to find a proper test for hack.
题目如上,翻译一下,正好提高一下英语:
小X最近遇到下面的问题。
我们定义f(x)为x的各个位的和(比如,f(1234) = 1 + 2 + 3 + 4)。你应该去计算从L到R所有f(i)的和,然后模上a。
当然,小X已经很快的解决了这个问题,并且已经锁住了他的代码,然后想要尽力hack其他人。他看到了下面的C++代码:
ans = solve(l, r) % a;
if (ans <= 0)
ans += a;
这个代码仅仅会在模a 等于0的情况下失败。你知道了a,请你帮助小X找出一个合适的测试数据来hack这个代码。
题目意思就是这样。
也就说,我们需要找出一个区间来使他们的f(i)和为a的倍数。。a 数据范围为 10^18。。
对于 x < 10^18,f(x + 10^18) = f(x) + 1。。这个还比较好理解,也就是说,x的各位和仅仅+1。这点是因为,高位+1,低位不变。。
那么 solve(x + 1, x + 10^18) = solve(x, x + 10^18 - 1) + 1。这又是什么也呢??
我们知道两个solve的区间都为 10^18 - x。只是前面solve的区间左起点 + 1。。
x , x+1 ..... x + 10^18 - 1 , x + 10^18
x , x + 1 .....x + 10^18 - 1 , x + 10^18
可以看到,[x + 1, x + 10^18] 区间 和[x, x + 10^18 -1]区间就是错开了一个x 和 x + 10^18。。
我们知道f(x + 10^18) = f(x) + 1。 也就是说[x, x + 10^18 - 1] 向右移一位,区间长度不变。他的f值和就+1。。。
这一点还是比较有保证的。。。
还有一个结论好像,好多人也是知道的。。表示弱渣有长知识了。。。。
g(10^x) = 45 * x * 10^(x-1)。。g(10^x) 表示从1 - (10^1 - 1) 的各个位置和。。
这样我们就可以很简单的计算出solve (0, 10^18) 的值了。。
也就很容易的计算出 solve(0, 10^18) % a = k 。。那么,我们只需要把区间去起点右移 k - a 位就 ok了。。
只能在次感叹数学的牛X。。
Code:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
using namespace std;
#define INT __int64
const INT x = 1e17;
int main()
{
INT a;
cin >> a;
INT L = 5 * (9 * (18 * x % a) % a) % a;
printf("%I64d %I64d\n", a - L, x * 10 - 1 + a - L);
return 0;
}
好题!!