CF468CHack it!

Posted stoorz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF468CHack it!相关的知识,希望对你有一定的参考价值。

题目

题目链接:https://codeforces.com/problemset/problem/468/C
给定正整数 \\(n\\),记 \\(f(i)\\) 表示 \\(i\\) 各位数字之和,求满足 \\(1\\leq l\\leq r\\leq 10^{200}\\) 的数 \\(l,r\\),使得

\\[\\left(\\sum^{r}_{i=l}f(i)\\right)\\bmod n=0 \\]

\\(n\\leq 10^{18}\\)

思路

对于 \\(<10^{18}\\) 的任意数字 \\(x\\),显然有 \\(f(x)+1=f(x+10^{18})\\)
我们先设 \\(l=1,r=10^{18}\\),记此时 \\(\\left(\\sum^{r}_{i=l}f(i)\\right)\\bmod n=x\\),那么每当我们令 \\(l,r\\) 同时加一,那么 \\(x\\) 也会随着加一。
所以我们只需要不断增加 \\(l,r\\),使得 \\(x=n\\) 即可。
问题转化为求 \\(\\left(\\sum^{10^{18}}_{i=1}f(i)\\right)\\bmod n\\) 的值,先把 \\(10^{18}\\) 扔掉,考虑 \\(1\\sim 10^{18}-1\\) 的每一位,不难发现对于每一位,每一个数字出现的次数恰好是 \\(10^{17}\\) 次。
所以 \\(\\sum^{10^{18}-1}_{i=1}f(i)=45\\times 10^{17}\\times 18=81\\times 10^{18}\\)。在加上 \\(f(10^{18})=1\\) 即可。
然后就可以轻松构造出合法的区间了。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll n,m;

int main()
{
	scanf("%I64d",&n);
	m=n-9000000000000000000LL%n*9LL%n;
	cout<<m<<" "<<999999999999999999LL+m;
	return 0;
}

以上是关于CF468CHack it!的主要内容,如果未能解决你的问题,请参考以下文章

CF468B Two Sets

[CF468D] Tree

cf468B Two Sets

CF468BTwo Sets

CF468D Tree(树的重心)

[51nod][cf468D]1558 树中的配对