从 古代猪文 到 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\) ,有两个难点:

  1. \(\sum C_n^d\) 的值可能很大,甚至爆 \(ll\) ,无法直接计算。

  2. \(C^d_n\) 无法直接用常规数学方法计算。

我们考虑解决这两个问题:

  1. 欧拉定理(在这题中等价于费马小定理),由于 \(p = 999911659\) 是一个质数,所以 \(G^k \bmod p = G ^ {k \bmod (p - 1)} \bmod p\) 。可以解决第一个难点。

  2. 对于 \(C_n^d\) 的计算,我们这里只能使用 \(Lucas\) 定理。而原题给的 \((p - 1) = 999911658 = 2 \times 3 \times 4679 \times 35617\) ,我们可以将质数先拆开再用中国剩余定理合并。

总复杂度 \(O(\sqrt{n} \log n)\)

然后这题就被解决了。

Code

不过这题我 WA 了三千七百万多次,原因有很多:

  1. 阶乘得求到 \(35617+\) ,别求少了 && 别数组开小了。

  2. \(Luscas\) 边界 if(x == 0 || y == 0) return 1; 别忘了判。

  3. 计算组合数时 \(n < m\) 时 答案为 0 。

数论全家桶

逆元 快速幂 线性筛 裴蜀定理 欧拉定理 整除分块 BSGS算法 卢卡斯定理 扩展欧几里得 中国剩余定理

posted @ 2021-11-16 23:35  BrotherCall  阅读(82)  评论(0编辑  收藏  举报