【CodeForces 468C】Hack it!

链接:

洛谷

博客园

题目大意:

\(f(x)\) 表示 \(x\) 的各个数位之和。

给定一个正整数 \(a\),请您找到 \(l,r\) 满足 \(\sum\limits_{i=l}^r f(i)\equiv0\pmod{a}\)

\(1\leq l,r\leq 10^{200}\)\(1\leq a\leq10^{18}\)

正文:

是道神仙题。首先有一个显而易见的性质:当 \(f(x)=x\) 时,\(f(x+10^{18})=x+1\)(这里加上 \(10^{18}\) 是因为这是 \(a\) 的上界)。

那么当 \(\sum\limits_{i=0}^{10^{18}-1}f(i)\equiv x\pmod{a}\),则有:

\[\sum\limits_{i=1}^{10^{18}}f(i)\equiv x+1\pmod{a} \]

以此类推得到:

\[\sum\limits_{i=a-x}^{10^{18}-1+a-x}f(i)\equiv x+a-x\equiv 0\pmod{a} \]

所以我们可以得到一组 \([a-x,10^{18}-1+a-x]\) 的解。接下来的问题就可以转化到如何求 \(\sum\limits_{i=0}^{10^{18}-1}f(i)\) 了。


然后根据初赛知识,这个玩意可以递归求得。

先设函数 \(F(x)=\sum_{i=0}^{10^x-1}f(i)\),它可以这么递归:

\[F(x)=\left\{\begin{matrix} 45&(x=1)\\ 45\times10^{x-1}+10F(x-1)&(x>1) \end{matrix}\right.\]

然后就可以暴力实现了:

ll qpow(ll a, int b)
{
	ll ans = 1;
	for (; b; a *= a, b >>= 1)
		if(b & 1) ans *= a;
	return ans;
}

ll F(int x)
{
	return x == 1? 45ll: 45ll * qpow(10, x - 1) + 10ll * F(x - 1);
}

int main()
{
	printf ("%lld\n", F(17));
	return 0;
}

这里直接算 \(F(18)\) 会溢出,所以先算出 \(F(17)=7.65\times10^{18}\),然后用电脑上自带的计算器得到 \(F(18)=8.1\times 10^{19}\)。于是便得到了答案。

代码:

ll n, inf = 1e18;

int main()
{
	scanf ("%lld", &n);
	ll l = n - inf % n * 9 % n * 9 % n, r = inf + l - 1; //注意这里直接乘81会溢出,所以乘两遍9。
	printf ("%lld %lld\n", l, r);
	return 0;
}
posted @ 2021-03-15 20:49  Jayun  阅读(99)  评论(0编辑  收藏  举报