745 Sum of Squares
对任意正数 , 是最大的能被 整除的完全平方数。
比如 。
定义 例如 。
求 ,结果模 。
非常大,遍历肯定是不现实的。
但是小于这个值的完全平方数只有 个,遍历几遍也足够快。如果知道了所有的完全平方数的根,那么其完全平方数及其整倍数 对应的 就得到了。直观地看,有很多 ,其 都是1。
我们只需要计算每个完全平方数的根 是多少个 的次数即可(即满足 的 的个数),因为计算 的时候可以用完全平方数乘以次数。
如果两个完全平方数的根 ,有关系 ,那么计算平方数及其整倍数的时候需要注意一下。,但是 也能整除 。所以我们需要从大的平方根向小的平方根遍历,对于后者 ,对应的 个数(即满足 的 的个数),需要减去 对应的 的个数。
首先定义几个常量
private static readonly long N = 100_000_000_000_000;
private static readonly int NSqrt = 10_000_000;
private static readonly int Mod = 1_000_000_007;
var counts = new long[NSqrt + 1];
for (long i = counts.Length - 1; i >= 2; i--)
{
long count = N / (i * i);
for (long j = i * 2; j < counts.Length; j += i)
{
count -= counts[j];
}
counts[i] = count;
}
sum
就是 的个数。现在加上完全平方数和对应次数的乘积。整个运算中,为了保持数很小(不超出 long
的范围),需要不停的取模。