题解 P2480 【[SDOI2010]古代猪文】

· · 题解

刚学数论3天,经此一全家桶~~深感恶心~~神清气爽,于是决定写这篇题解的同时,权当是我对简单数论的理解~~记忆力堪忧~~。 若有证明或书写错误错误,敬请斧正,蒟蒻将不胜感激。 因为作者是数论菜鸟,一惊一乍请大佬见谅。 $\operatorname{II}\quad \quad$前置芝士 [欧拉定理](https://baike.baidu.com/item/%E6%AC%A7%E6%8B%89%E5%AE%9A%E7%90%86/891345?fr=aladdin#2) ($or$ [费马小定理](https://baike.baidu.com/item/%E8%B4%B9%E9%A9%AC%E5%B0%8F%E5%AE%9A%E7%90%86)),[中国剩余定理](https://baike.baidu.com/item/%E5%AD%99%E5%AD%90%E5%AE%9A%E7%90%86?fromtitle=%E4%B8%AD%E5%9B%BD%E5%89%A9%E4%BD%99%E5%AE%9A%E7%90%86&fromid=11200132),[卢卡斯定理](https://baike.baidu.com/item/lucas/4326261)。 证明:下转$\operatorname{V}$区。 $\operatorname{III}\quad \quad$题解 ___ $\operatorname{Tips}$:如果有看不懂的定理或步骤,请移步证明区或评论区。 ___ 题目极其冗长,去其糟粕~~几乎全是糟粕~~之后: - 远古时期猪文文字总个数为 $n$。 - 那个朝代流传的猪文文字恰好为远古时期的 $\frac{1}{k}$,其中 $k$ 是 $n$ 的一个正约数(可以是 $1\ $或 $n$)。(枚举约数) - 然而从 $n$ 个文字中保留下 $\frac{n}{k}$ 个的情况也是相当多的。(即组合数) - 所有可能的 $k$ 的所有情况数加起来为 $p$ 的话,那么他研究古代文字的代价将会是 $g^p$。 可以得到题目真正需要求的柿子(枚举$n/d$与$d$是一样的,也为了好看): $$g^{\sum \limits_{d|n} \operatorname{C}_n^{d}} \operatorname{mod} 9999111659$$ $\operatorname{Case\ 1}:$当 $\quad \color{red}{999911659|g}\quad$时,$\operatorname{Ans}=0$;(一定要判!) $\operatorname{Case\ 2}:

由欧拉定理,或费马小定理(999911659为质数):

=g^{\sum \limits_{d|n} \operatorname{C}_n^{d} \operatorname{mod}999911658} \operatorname{mod} 9999111659

即求:

\sum \limits_{d|n} \operatorname{C}_n^{d} \operatorname{mod}999911658

然后————好像没辙了。

题目所要求的组合数的n,m的数量级高达10^9,只有卢卡斯定理可担此重任,但是……

我们怀着忐忑的心情将$999911658$分解质因数: $$999911658 = 2 \times3\times4679\times35617$$ 只有一次项! 这说明我们可以对四个质因子分别求解。 问题又来了,如何合并答案? 这次很简单:因为四个模数两两互质~~毕竟都是质数~~,所以中国剩余定理即可。 于是,我们来理一下思路: - 对四个模数分别求出$\sum \limits_{d|n} \operatorname{C}_n^{d} \operatorname{mod} p_i$的值分别为$ans_i$(其中组合数使用卢卡斯定理)。 - 用中国剩余定理求出线性同余方程组: $\begin{cases}S \equiv ans_1(\operatorname{mod}p_1) \\S \equiv ans_2(\operatorname{mod}p_2) \\S \equiv ans_3(\operatorname{mod}p_3)\\ S \equiv ans_4(\operatorname{mod}p_4)\end{cases}

的在\left[0,999911658\right] 中的解。

然后这题就做完了(好像也不是很难)。

```cpp #include <cstdio> #define int long long//记得开longlong <== Mod*mod > intmax! const int maxd = 36000,Mod = 999911659; int N,g; inline int ksm(int a,int x,int p) {//快速幂不解释 int ans = 1,base = a; while(x) { if(x & 1)ans = ans*base%p; base = base*base%p,x >>= 1; } return ans; } struct Lucas { int mod,pre[maxd],inv[maxd];//O(1)组合数准备:阶乘与阶乘逆元(逆元求法见注释) inline void getpreinv() { pre[0] = inv[0] = 1; for(int i=1; i<=mod-1; ++i)pre[i] = pre[i-1]*i%mod; inv[mod-1] = ksm(pre[mod-1],mod-2,mod);//单个使用快速幂 for(int i=mod-2; i; --i)inv[i] = inv[i+1]*(i+1)%mod; } inline int C(int m,int n) {return m>n?0:pre[n]*inv[m]%mod*inv[n-m]%mod;}//C(m,n) = n!/m!(n-m)! = n!*inv[m!]*inv[(n-m)!] inline int lucas(int m,int n) { if(m==0)return 1; return C(m%mod,n%mod)*lucas(m/mod,n/mod)%mod; }//Lucas定理 } S[5]; int mod[] = {0,2,3,4679,35617},sum[5],M[5],Mp[5]; signed main() { scanf("%lld %lld",&N,&g); if(g == Mod){printf("0");return 0;} for(int i=1; i<=4; ++i)S[i].mod = mod[i],S[i].getpreinv();//组合数预处理 for(int i=1;i*i<=N;++i)//枚举约数统计答案 if(N%i == 0) for(int j=1;j<=4;++j){ sum[j] = (sum[j]+S[j].lucas(i,N))%S[j].mod; if(i*i!=N)sum[j] = (sum[j]+S[j].lucas(N/i,N))%S[j].mod;//如果i==n/i则只算一次! } for(int i=1;i<=4;++i)M[i] = (Mod-1)/S[i].mod,Mp[i] = ksm(M[i],S[i].mod-2,S[i].mod); long long S = 0; for(int i=1;i<=4;++i)S += (long long)(M[i]*Mp[i]*sum[i]); S = (S%(Mod-1)+Mod-1)%(Mod-1);//中国剩余定理求法见证明区 printf("%lld",ksm(g,S,Mod)); return 0; } ``` 注释: - 阶乘逆元求法: > - 快速幂得到$((mod-1)!)^{-1}
___ $\operatorname{i}\quad $ 欧拉定理 注:费马小定理是欧拉定理的特殊情况,所以只证欧拉。 **定义**:(为了更好懂,省去了一点严谨性,大佬轻喷) - 同余类:所有除$m$余$i$的整数构成模$m$的一个同余类,记为$\overline{i}$. - 完全剩余系(并不重要):所有模m的同余类的集合。(即$\left\{\overline{0},\overline{1}\cdots\overline{m-1}\right\}$) - **简化剩余系**:在$\overline0\cdots \overline {m-1}$这$m$个同余类中,**余数与$m$互质**的同余类构成模$m$的简化剩余系。由定义易知,模$m$的简化剩余系中共有$\varphi(m)$个同余类。(注:$0$不与$m$互质)。 **证明**:(运算都在模$m$意义下进行) - 引理 : 当$\operatorname{gcd}(a,m) = 1$时,对于任意$b_i \neq b_j $,有$a\cdot b_i \neq a\cdot b_j

设模m的简化剩余系为\{\overline{b_1}\cdots\overline{b_{\varphi(m)}}\},由引理知,各个a\cdot b_i两两不同,所以\{\overline{a\cdot b_1}\cdots\overline{a\cdot b_{\varphi(m)}}\}也构成模m的简化剩余系。

\Rightarrow b_1\cdot b_2 \cdots b_{\varphi(m)} \equiv (a\cdot b_1)\cdot (a\cdot b_2) \cdots (a\cdot b_{\varphi(m)}) \equiv a^{\varphi(m)}\cdot b_1\cdot b_2 \cdots b_{\varphi(m)}

两边同乘 b_1\cdot b_2 \cdots b_{\varphi(m)}的逆元(\because \forall b_i,\operatorname{gcd}(b_i,m)=1,即存在逆元)

\Rightarrow a^{\varphi(m)} \equiv 1

证毕。

注: 代入m\in prime则有a^{m}\equiv a,即费马小定理。

其实就是个构造…… 我们有一个同余方程组,其中满足模数两两互质:

\begin{cases}S \equiv ans_1(\operatorname{mod}p_1) \ \vdots\ S \equiv ans_n(\operatorname{mod}p_n)\end{cases}

构造方案 : - 我们令$M = \prod m_i,m'_i = M/m_i$。 - 构造$t_i$满足$m'_i\cdot t_i \equiv 1(\operatorname{mod}m_i)

构造正确性证明:

实现 :

太神了,虽然证明很初等,但是我不会…… [挂链接跑路](https://zhuanlan.zhihu.com/p/116698264)(讲的真的好) ___ $\operatorname{VI}\quad $ 结束 虽然本文章极其初等~~甚至有些ZZ~~,数论菜鸟恳请大家斧正,这会对我后来的学习起到很大帮助,谢谢! 求过