P2480 [SDOI2010] 古代猪文

原题链接

简化题意: 给定 n , G n,G n,G,求 G ∑ d ∣ n C n d m o d 999911659 G^{\sum_{d|n}C_{n}^{d}}mod_{}999911659 GdnCndmod999911659

发现指数可能非常大,而模数为质数,此时可以考虑运用扩展欧拉定理来化简。
对于此题 G ∑ d ∣ n C n d m o d 999911659 = G ∑ d ∣ n C n d m o d 999911658 m o d 999911659 G^{\sum_{d|n}C_{n}^{d}}mod_{}999911659=G^{\sum_{d|n}C_{n}^{d}mod_{}999911658}mod_{}999911659 GdnCndmod999911659=GdnCndmod999911658mod999911659

而发现 999911658 999911658 999911658 却不是质数,此时可以先对其质因数分解,若其质因数的指数均为 1 1 1,那就好办了。可以运用中国剩余定理来求解。

具体的,对于此题,可以得到如下同余方程组:
{ x ≡ ∑ d ∣ n C n d ( m o d 2 ) x ≡ ∑ d ∣ n C n d ( m o d 3 ) x ≡ ∑ d ∣ n C n d ( m o d 4679 ) x ≡ ∑ d ∣ n C n d ( m o d 35617 ) \left\{\begin{matrix}x\equiv\sum_{d|n}C_{n}^{d}(mod_{}2) \\x\equiv\sum_{d|n}C_{n}^{d}(mod_{}3) \\x\equiv\sum_{d|n}C_{n}^{d}(mod_{}4679) \\x\equiv\sum_{d|n}C_{n}^{d}(mod_{}35617) \end{matrix}\right. xdnCnd(mod2)xdnCnd(mod3)xdnCnd(mod4679)xdnCnd(mod35617)

然后就可以运用 Lucas 定理求出这些组合数之和,再上 CRT 求出 x x x,答案就是 G x m o d 999911659 G^xmod_{}999911659 Gxmod999911659

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=50010,Mod=999911659,mod=999911658;

int n,G,fac[N],infac[N],prime[N],cnt,d[N],tot,a[N];

int qpow(int a,int b,int p){//快速幂
	int res=1;
	while(b){
		if(b&1) res=res*a%p;
		b>>=1,a=a*a%p;
	}
	return res;
}

void solve(int x){//对mod质因数分解
	for(int i=2;i*i<=mod;i++){
		if(x%i==0){
			prime[++cnt]=i;
			while(x%i==0) x/=i;
		}
	}
	if(x!=1) prime[++cnt]=x;
}

void divide(int x){//求n的约数
	for(int i=1;i*i<=n;i++){
		if(n%i==0){
			d[++tot]=i;
			if(i!=n/i) d[++tot]=n/i;
		}
	}
}

void init(int p){//预处理模p意义下的组合数
	fac[0]=1;
	for(int i=1;i<=p;i++) fac[i]=fac[i-1]*i%p;
	infac[p]=0,infac[p-1]=qpow(fac[p-1],p-2,p);
	for(int i=p-2;i>=0;i--) infac[i]=infac[i+1]*(i+1)%p;
}

int C(int n,int m,int p){
	if(n<m) return 0;
	return fac[n]*infac[m]%p*infac[n-m]%p;
}

int Lucas(int n,int m,int p){//Lucas定理求组合数
	if(m==0) return 1;
	return C(n%p,m%p,p)*Lucas(n/p,m/p,p)%p;
}

void cal(int x){//求每个数的那个sigma
	init(prime[x]);
	for(int i=1;i<=tot;i++){
		a[x]=(a[x]+Lucas(n,d[i],prime[x]))%prime[x];
	}
}

int CRT(){//中国剩余定理
	int ans=0;
	for(int i=1;i<=cnt;i++){
		int m=mod/prime[i],inv=qpow(m,prime[i]-2,prime[i]);
		ans=(ans+a[i]%mod*m%mod*inv%mod)%mod;
	}
	return (ans+mod)%mod;
}

signed main(){
	
	ios::sync_with_stdio(false);
	cin>>n>>G;
	if(G%Mod==0){cout<<0<<endl;return 0;}
	solve(mod),divide(n);
	for(int i=1;i<=cnt;i++) cal(i);
	cout<<qpow(G,CRT(),Mod)<<endl;//终于搞定了TAT
	
	return 0;
}
请转成markdown语法 中国剩余定理 引入 「物不知数」问题:有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何? 即求满足以下条件的整数:除以 3 余 2,除以 5 余 3,除以 7 余 2。 该问题最早见于《孙子算经》中,并有该问题的具体解法。宋朝数学家秦九韶于 1247 年《数书九章》卷一、二《大衍类》对「物不知数」问题做出了完整系统的解答。上面具体问题的解答口诀由明朝数学家程大位在《算法统宗》中给出: 三人同行七十希,五树梅花廿一支,七子团圆正半月,除百零五便得知。 2\times 70+3\times 21+2\times 15=233=2\times 105+23,故答案为 23。 定义 中国剩余定理 (Chinese Remainder Theorem, CRT) 可求解如下形式的一元线性同余方程组(其中 n_1, n_2, \cdots, n_k 两两互质): \begin{cases} x &\equiv a_1 \pmod {n_1} \\ x &\equiv a_2 \pmod {n_2} \\ &\vdots \\ x &\equiv a_k \pmod {n_k} \\ \end{cases} 上面的「物不知数」问题就是一元线性同余方程组的一个实例。 过程 计算所有模数的积 n; 对于第 i 个方程: 计算 m_i=\frac{n}{n_i}; 计算 m_i 在模 n_i 意义下的 逆元 m_i^{-1}; 计算 c_i=m_im_i^{-1}(不要对 n_i 取模)。 方程组在模 n 意义下的唯一解为: x=\sum_{i=1}^k a_ic_i \pmod n。 实现 C++ Python LL CRT(int k, LL* a, LL* r) { LL n = 1, ans = 0; for (int i = 1; i <= k; i++) n = n * r[i]; for (int i = 1; i <= k; i++) { LL m = n / r[i], b, y; exgcd(m, r[i], b, y); // b * m mod r[i] = 1 ans = (ans + a[i] * m * b % n) % n; } return (ans % n + n) % n; } 证明 我们需要证明上面算法计算所得的 x 对于任意 i=1,2,\cdots,k 满足 x\equiv a_i \pmod {n_i}。 当 i\neq j 时,有 m_j \equiv 0 \pmod {n_i},故 c_j \equiv m_j \equiv 0 \pmod {n_i}。又有 c_i \equiv m_i \cdot (m_i^{-1} \bmod {n_i}) \equiv 1 \pmod {n_i},所以我们有: \begin{aligned} x&\equiv \sum_{j=1}^k a_jc_j &\pmod {n_i} \\ &\equiv a_ic_i &\pmod {n_i} \\ &\equiv a_i \cdot m_i \cdot (m^{-1}_i \bmod n_i) &\pmod {n_i} \\ &\equiv a_i &\pmod {n_i} \end{aligned} 即对于任意 i=1,2,\cdots,k,上面算法得到的 x 总是满足 x\equiv a_i \pmod{n_i},即证明了解同余方程组的算法的正确性。 因为我们没有对输入的 a_i 作特殊限制,所以任何一组输入 \{a_i\} 都对应一个解 x。 另外,若 x\neq y,则总存在 i 使得 x 和 y 在模 n_i 下不同余。 故系数列表 \{a_i\} 与解 x 之间是一一映射关系,方程组总是有唯一解。 解释 下面演示 CRT 如何解「物不知数」问题。 n=3\times 5\times 7=105; 三人同行 七十 希: n_1=3, m_1=n/n_1=35, m_1^{-1}\equiv 2\pmod 3,故 c_1=35\times 2=70; 五树梅花 廿一 支: n_2=5, m_2=n/n_2=21, m_2^{-1}\equiv 1\pmod 5,故 c_2=21\times 1=21; 七子团圆正 半月: n_3=7, m_3=n/n_3=15, m_3^{-1}\equiv 1\pmod 7,故 c_3=15\times 1=15; 所以方程组的唯一解为 x\equiv 2\times 70+3\times 21+2\times 15\equiv 233\equiv 23 \pmod {105}。(除 百零五 便得知) Garner 算法 CRT 的另一个用途是用一组比较小的质数表示一个大的整数。 例如,若 a 满足如下线性方程组,且 a < \prod_{i=1}^k p_i(其中 p_i 为质数): \begin{cases} a &\equiv a_1 \pmod {p_1} \\ a &\equiv a_2 \pmod {p_2} \\ &\vdots \\ a &\equiv a_k \pmod {p_k} \\ \end{cases} 我们可以用以下形式的式子(称作 a 的混合基数表示)表示 a: a = x_1 + x_2 p_1 + x_3 p_1 p_2 + \ldots + x_k p_1 \ldots p_{k-1} Garner 算法 将用来计算系数 x_1, \ldots, x_k。 令 r_{ij} 为 p_i 在模 p_j 意义下的 逆: p_i \cdot r_{i,j} \equiv 1 \pmod{p_j} 把 a 代入我们得到的第一个方程: a_1 \equiv x_1 \pmod{p_1} 代入第二个方程得出: a_2 \equiv x_1 + x_2 p_1 \pmod{p_2} 方程两边减 x_1,除 p_1 后得 \begin{aligned} a_2 - x_1 &\equiv x_2 p_1 &\pmod{p_2} \\ (a_2 - x_1) r_{1,2} &\equiv x_2 &\pmod{p_2} \\ x_2 &\equiv (a_2 - x_1) r_{1,2} &\pmod{p_2} \end{aligned} 类似地,我们可以得到: x_k=(\dots((a_k-x_1)r_{1,k}-x_2)r_{2,k})-\dots)r_{k-1,k} \bmod p_k 实现 该算法的时间复杂度为 O(k^2)。实际上 Garner 算法并不要求模数为质数,只要求模数两两互质,我们有如下伪代码: \begin{array}{ll} &\textbf{Chinese Remainder Algorithm }\operatorname{cra}(\mathbf{v}, \mathbf{m})\text{:} \\ &\textbf{Input}\text{: }\mathbf{m}=(m_0,m_1,\dots ,m_{n-1})\text{, }m_i\in\mathbb{Z}^+\land\gcd(m_i,m_j)=1\text{ for all } i\neq j\text{,} \\ &\qquad \mathbf{v}=(v_0,\dots ,v_{n-1}) \text{ where }v_i=x\bmod m_i\text{.} \\ &\textbf{Output}\text{: }x\bmod{\prod_{i=0}^{n-1} m_i}\text{.} \\ 1&\qquad \textbf{for }i\text{ from }1\text{ to }(n-1)\textbf{ do} \\ 2&\qquad \qquad C_i\gets \left(\prod_{j=0}^{i-1}m_j\right)^{-1}\bmod{m_i} \\ 3&\qquad x\gets v_0 \\ 4&\qquad \textbf{for }i\text{ from }1\text{ to }(n-1)\textbf{ do} \\ 5&\qquad \qquad u\gets (v_i-x)\cdot C_i\bmod{m_i} \\ 6&\qquad \qquad x\gets x+u\prod_{j=0}^{i-1}m_j \\ 7&\qquad \textbf{return }(x) \end{array} 可以发现在第六行中的计算过程对应上述混合基数的表示。 应用 某些计数问题或数论问题出于加长代码、增加难度、或者是一些其他原因,给出的模数:不是质数! 但是对其质因数分解会发现它没有平方因子,也就是该模数是由一些不重复的质数相乘得到。 那么我们可以分别对这些模数进行计算,最后用 CRT 合并答案。 下面这道题就是一个不错的例子。 洛谷 P2480 [SDOI2010] 古代 给出 G,n( 1 \leq G,n \leq 10^9),求: G^{\sum_{k\mid n}\binom{n}{k}} \bmod 999~911~659 首先,当 G=999~911~659 时,所求显然为 0。 否则,根据 欧拉定理,可知所求为: G^{\sum_{k\mid n}\binom{n}{k} \bmod 999~911~658} \bmod 999~911~659 现在考虑如何计算: \sum_{k\mid n}\binom{n}{k} \bmod 999~911~658 因为 999~911~658 不是质数,无法保证 \forall x \in [1,999~911~657], x 都有逆元存在,上面这个式子我们无法直接计算。 注意到 999~911~658=2 \times 3 \times 4679 \times 35617,其中每个质因子的最高次数均为一,我们可以考虑分别求出 \sum_{k\mid n}\binom{n}{k} 在模 2, 3, 4679, 35617 这几个质数下的结果,最后用中国剩余定理来合并答案。 也就是说,我们实际上要求下面一个线性方程组的解: \begin{cases} x \equiv a_1 \pmod 2\\ x \equiv a_2 \pmod 3\\ x \equiv a_3 \pmod {4679}\\ x \equiv a_4 \pmod {35617} \end{cases} 而计算一个组合数对较小的质数取模后的结果,可以利用 卢卡斯定理扩展:模数不互质的情况 两个方程 设两个方程分别是 x\equiv a_1 \pmod {m_1}、 x\equiv a_2 \pmod {m_2}; 将它们转化为不定方程: x=m_1p+a_1=m_2q+a_2,其中 p, q 是整数,则有 m_1p-m_2q=a_2-a_1。 由 裴蜀定理,当 a_2-a_1 不能被 \gcd(m_1,m_2) 整除时,无解; 其他情况下,可以通过 扩展欧几里得算法 解出来一组可行解 (p, q); 则原来的两方程组成的模方程组的解为 x\equiv b\pmod M,其中 b=m_1p+a_1, M=\text{lcm}(m_1, m_2)。 多个方程 用上面的方法两两合并即可。
08-16
<think>好的,我现在需要处理用户关于中国剩余定理(CRT)的请求。用户希望将提供的详细解释和示例代码转换为Markdown格式。首先,我需要仔细阅读用户提供的材料,确保理解每个部分的结构和内容。 首先,用户提供的材料包括中国剩余定理的定义、过程、实现代码、证明、解释、Garner算法、应用以及扩展部分。每个部分都有详细的说明和示例,比如“物不知数”问题的具体解法,C++和Python的代码示例,以及如何应用CRT解决实际问题的例子,如洛谷P2480题目。 接下来,我需要将这些内容组织成Markdown格式。Markdown的结构通常包括标题、子标题、代码块、列表和数学公式。用户提供的材料中有很多数学公式,需要使用LaTeX语法正确表示。例如,同余方程组、模数积的计算、逆元的求解等。同时,代码部分需要用代码块包裹,并指定语言类型,如C++或Python。 需要注意的是,用户可能在转换过程中希望保持原有的格式,比如定义、过程、证明等部分的分段。此外,用户提供的材料中有一些中英混合的内容,需要确保术语的一致性,比如“Chinese Remainder Theorem”应翻译为“中国剩余定理”,但保留英缩写CRT。 在转换过程中,还需要处理用户提到的“§§相关问题§§”部分。用户要求在回答末尾添加3-5个相关问题,这些问题必须基于用户的问题和回答内容。例如,关于CRT的应用场景、如何处理模数不互质的情况、Garner算法的时间复杂度等。 可能遇到的挑战包括正确格式化数学公式,确保代码块正确显示,以及保持内容的连贯性。例如,用户提供的代码中有一些中注释,需要保留或适当处理。此外,材料中的一些步骤和证明需要清晰分段,使用Markdown的列表和标题来增强可读性。 最后,检查转换后的Markdown是否符合规范,确保所有链接、代码块和数学公式正确无误。同时,确保在回答末尾添加了相关问题,这些问题需要与CRT相关,并且基于用户提供的材料内容。 </think> ```markdown # 中国剩余定理 (Chinese Remainder Theorem, CRT) ## 引入 **「物不知数」问题**:有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何? 即求满足以下条件的整数: - 除以 3 余 2 - 除以 5 余 3 - 除以 7 余 2 该问题最早见于《孙子算经》,宋朝数学家秦九韶在《数书九章》中系统解答。明朝数学家程大位在《算法统宗》中给出解法口诀: > 三人同行七十希,五树梅花廿一支,七子团圆正半月,除百零五便得知。 解: $2 \times 70 + 3 \times 21 + 2 \times 15 = 233 = 2 \times 105 + 23$,故答案为 **23**。 --- ## 定义 中国剩余定理用于求解如下形式的一元线性同余方程组(模数 $n_1, n_2, \cdots, n_k$ 两两互质): $$ \begin{cases} x \equiv a_1 \pmod{n_1} \\ x \equiv a_2 \pmod{n_2} \\ \vdots \\ x \equiv a_k \pmod{n_k} \end{cases} $$ --- ## 过程 1. **计算模数的积**:$n = n_1 \times n_2 \times \cdots \times n_k$。 2. **对第 $i$ 个方程**: - 计算 $m_i = \frac{n}{n_i}$。 - 计算 $m_i$ 在模 $n_i$ 意义下的逆元 $m_i^{-1}$。 - 计算 $c_i = m_i \cdot m_i^{-1}$(不取模)。 3. **唯一解**: $$ x = \left( \sum_{i=1}^k a_i c_i \right) \pmod{n} $$ --- ## 实现 ### C++ 代码 ```cpp LL CRT(int k, LL* a, LL* r) { LL n = 1, ans = 0; for (int i = 1; i <= k; i++) n *= r[i]; for (int i = 1; i <= k; i++) { LL m = n / r[i], b, y; exgcd(m, r[i], b, y); // b * m ≡ 1 mod r[i] ans = (ans + a[i] * m * b % n) % n; } return (ans % n + n) % n; } ``` ### Python 代码 ```python def crt(a_list, m_list): n = 1 for m in m_list: n *= m result = 0 for a, m in zip(a_list, m_list): mi = n // m inv = pow(mi, -1, m) # 模逆元 result += a * mi * inv return result % n ``` --- ## 证明 需证明算法解 $x$ 满足 $x \equiv a_i \pmod{n_i}$ 对所有 $i$ 成立。 - 对于 $i \neq j$,$m_j \equiv 0 \pmod{n_i}$,故 $c_j \equiv 0 \pmod{n_i}$。 - 对于 $c_i$,$c_i \equiv m_i \cdot m_i^{-1} \equiv 1 \pmod{n_i}$。 - 因此: $$ x \equiv \sum_{j=1}^k a_j c_j \equiv a_i c_i \equiv a_i \pmod{n_i} $$ --- ## Garner 算法 用于将大整数表示为一组小质数的混合基数形式: $$ a = x_1 + x_2 p_1 + x_3 p_1 p_2 + \cdots + x_k p_1 p_2 \cdots p_{k-1} $$ **步骤**: 1. 计算 $r_{ij}$ 为 $p_i$ 在模 $p_j$ 下的逆元。 2. 递推计算系数 $x_k$: $$ x_k = \left( \cdots \left( (a_k - x_1) r_{1,k} - x_2 \right) r_{2,k} - \cdots \right) r_{k-1,k} \pmod{p_k} $$ --- ## 应用 **示例**:洛谷 P2480 [SDOI2010] 古代 求 $G^{\sum_{k \mid n} \binom{n}{k}} \bmod 999911659$。 1. 分解模数:$999911658 = 2 \times 3 \times 4679 \times 35617$。 2. 分别计算 $\sum_{k \mid n} \binom{n}{k}$ 对每个质因数的模。 3. 用 CRT 合并结果。 --- ## 扩展:模数不互质的情况 **两方程合并**: 1. 转化为不定方程:$x = m_1 p + a_1 = m_2 q + a_2$。 2. 由裴蜀定理,当 $\gcd(m_1, m_2) \nmid (a_2 - a_1)$ 时无解。 3. 否则用扩展欧几里得算法求解,合并为 $x \equiv b \pmod{\text{lcm}(m_1, m_2)}$。 **多方程合并**:两两合并即可。 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值