【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;
}