CodeForces 468C Hack it![数学]

题目链接: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;
}

好题!!



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值