684 Inverse Digit Sum
的定义是数字之和是 的最小值,比如 。
,题中给出 ,可以用于检测程序是否基本正确。
是斐波那契数列。问题是求 模 1000000007。
斐波那契数列以指数速度增长,所以暴力法肯定是不行的(快接近 long
的表示上限了),那么需要在常数或者对数时间复杂度的算出 的算法。
其实很容易想,数字最小,那么就是高位的值越小越好,那么低位的值都是9即可。
有了 ,我们就可以推导一下 了。
可以写作是 ,其中 是 ,后面 9 的个数是 ,不妨记作 。
那么 可以分成两个部分。第一部分(记作 )是所有长度和 一样的数之和,第二部分(记作 )是数字长度为 的数之和。 长度为 的数之和和上式类似,其中 , 减一。 所以 由于 很大,那么 也很大, 非常大,所以需要利用分治法以对数时间复杂度快速算出其模 1000000007 的值。
private static long GetRemainder(long l)
{
if (l < 10)
{
return (long)Math.Pow(10, l);
}
var r = l % 2;
var half = GetRemainder(l / 2);
half = (half * half) % Mod;
if (r == 0)
{
return half;
}
else
{
return (half * 10) % Mod;
}
}