从 古代猪文 到 noip 数论全家桶
古代猪文
前两天看机房里的巨佬都在卷这道题,说是数论全家桶,于是我决定追随大佬们的步伐,切掉这题!!!
然后从头 WA 到尾 ...
所以我在这里简要简述一下数论问题的各大坑点以及 noip 能考到的 数论全家桶。
先从 古代猪文 这题开始入手吧。
题意是:给定 \(n\) 和 \(G\) , 求 \(G^{\sum_{d|n} C^d_n} \bmod 999911659\) 。\(n , G \leqslant 10^9\) 。
我们从外向内展开一下这个式子。
最外层相当于一个 \(G^k \bmod 999911659\) ,可以快速幂直接莽 ,复杂度 \(O(\log_2k)\) 。
中间一层是枚举 \(d\) ,复杂度为 \(O(\sqrt{n})\) ,可以接受。
但对于最内层的 \(\sum C_n^d\) ,有两个难点:
-
\(\sum C_n^d\) 的值可能很大,甚至爆 \(ll\) ,无法直接计算。
-
\(C^d_n\) 无法直接用常规数学方法计算。
我们考虑解决这两个问题:
-
欧拉定理(在这题中等价于费马小定理),由于 \(p = 999911659\) 是一个质数,所以 \(G^k \bmod p = G ^ {k \bmod (p - 1)} \bmod p\) 。可以解决第一个难点。
-
对于 \(C_n^d\) 的计算,我们这里只能使用 \(Lucas\) 定理。而原题给的 \((p - 1) = 999911658 = 2 \times 3 \times 4679 \times 35617\) ,我们可以将质数先拆开再用中国剩余定理合并。
总复杂度 \(O(\sqrt{n} \log n)\) 。
然后这题就被解决了。
不过这题我 WA 了三千七百万多次,原因有很多:
-
阶乘得求到 \(35617+\) ,别求少了 && 别数组开小了。
-
\(Luscas\) 边界
if(x == 0 || y == 0) return 1;
别忘了判。 -
计算组合数时 \(n < m\) 时 答案为 0 。