codeforces 100633J. Ceizenpok’s formula (扩展Lucas定理+中国剩余定理)

J. Ceizenpok’s formula
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Dr. Ceizenp'ok from planet i1c5l became famous across the whole Universe thanks to his recent discovery — the Ceizenpok’s formula. This formula has only three arguments: nk and m, and its value is a number of k-combinations of a set of n modulo m.

While the whole Universe is trying to guess what the formula is useful for, we need to automate its calculation.

Input

Single line contains three integers nkm, separated with spaces (1 ≤ n ≤ 10180 ≤ k ≤ n2 ≤ m ≤ 1 000 000).

Output

Write the formula value for given arguments nkm.

Examples
input
2 1 3
output
2
input
4 2 5
output
1


题解:扩展Lucas定理+中国剩余定理

快速乘要少用,死慢啊!!

各种地方炸掉,我也是醉了。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 20
#define LL long long
using namespace std;
LL n,m,M,a[N];
LL p[1000003],mod[1000003],cnt;
void get_prime(LL k)
{
	LL x=k;
	for (LL i=2;i*i<=x;i++) 
	 if (x%i==0) {
	    ++cnt; p[cnt]=i; mod[cnt]=1;
	    while (x%i==0) {
	    	x/=i;
	    	mod[cnt]*=i;
		}
	 }
	if (x>1) {
		p[++cnt]=x;
		mod[cnt]=x;
	}
}
LL mul(LL a,LL b,LL mod)
{
	LL res=0;
	while (b) {
		if (b&1) res=(res+a)%mod;
		a=(a+a)%mod;
		b>>=1;
	}
	return res;
}
LL quickpow(LL num,LL x,LL p)
{
	LL base=num%p; LL ans=1;
	while (x) {
		if (x&1) ans=(ans*base)%p;
		x>>=1;
		base=(base*base)%p;
	}
	return ans;
}
void exgcd(LL a,LL b,LL &x,LL &y)
{
	if (b==0) {
		x=1; y=0; return;
	}
	exgcd(b,a%b,x,y);
	LL t=y; 
	y=x-(a/b)*y;
	x=t;
}
LL inverse(LL a,LL b)
{
	LL x,y;
	exgcd(a,b,x,y);
	x=(x%b+b)%b;
	if (!x) x+=b; 
	return x;
}
LL solve(int k1,LL n)
{
	if (n==0) return 1;
	LL ans=1;
	for (LL i=2;i<mod[k1];i++) 
	 if (i%p[k1]) ans=ans*i%mod[k1];
	ans=quickpow(ans,n/mod[k1],mod[k1]);
	for (LL i=2;i<=n%mod[k1];i++)
	 if (i%p[k1]) ans=ans*i%mod[k1];
	return ans*solve(k1,n/p[k1])%mod[k1];
}
LL calc(int k,LL n,LL m)
{
	if (m>n) return 0;
    LL a=solve(k,n),b=solve(k,m),c=solve(k,n-m);
    LL k1=0,ans;
    for (LL i=n;i;i/=p[k]) k1+=i/p[k];
    for (LL i=m;i;i/=p[k]) k1-=i/p[k];
    for (LL i=n-m;i;i/=p[k]) k1-=i/p[k];
    ans=a*inverse(b,mod[k])%mod[k]*inverse(c,mod[k])%mod[k]*quickpow(p[k],k1,mod[k])%mod[k];
    return ans;
}
LL china()
{
	LL x,y,ans=0;
    for (int i=1;i<=cnt;i++){
    	LL r=M/mod[i];
    	ans=(ans+r*inverse(r,mod[i])%M*a[i]%M)%M;
	}
	return ans%M;	
}
int main()
{
//	freopen("a.in","r",stdin);
//	freopen("my.out","w",stdout);
	cin>>n>>m>>M;
	get_prime(M);
	//for (int i=1;i<=cnt;i++) cout<<p[i]<<" "<<mod[i]<<endl;
	for (int i=1;i<=cnt;i++)
	 a[i]=calc(i,n,m);
	printf("%I64d\n",china());
}



<think>好的,用户现在在Codeforces平台上查找与中国剩余定理相关的题目或解决方案。我需要根据用户提供的引用内容以及之前的回答来提供帮助。首先,回顾之前的对话,用户已经得到了一些关于中国剩余定理(CRT)的示例题目和C++代码,以及相关问题。现在用户进一步询问具体的题目和解法,可能需要更详细的题目链接、分类或具体解题思路。 用户提供的引用中有几个代码示例和问题描述,例如HDOJ 1788、Codeforces 710D等。我需要将这些内容整合起来,给出用户在Codeforces上可能遇到的CRT相关题目类型和解决方法。注意用户可能需要题目编号、难度、关键解法步骤,以及如何应用扩展中国剩余定理(exCRT)等。 首先,确定用户的需求是查找Codeforces上的CRT题目和解法。需要确认用户是否了解CRT的基本原理,或者是否需要先复习理论。根据之前的回答,用户可能已经有一定基础,现在需要具体应用。 接下来,分析用户提供的引用内容。引用[1]是关于HDOJ的一道题,但用户主要关注Codeforces,所以可能不需要深入讨论。引用[3]提到Codeforces 710D,使用扩展CRT,这应该是重点。引用[2]和[4]涉及其他数论问题,可能与CRT关联不大,但需要判断是否有间接联系。 用户可能需要知道Codeforces上哪些题目明确使用CRT或exCRT,比如Div2的某些题目。例如,710D题目需要解两个线性同余方程,并计算区间内的解的数量,这正是exCRT的应用场景。此外,可能还有其他题目,比如涉及模运算或同余方程组的问题。 然后,需要组织信息,将题目按难度分类,给出题目链接、关键解法和注意事项。同时,可能需要解释exCRT与标准CRT的区别,以及如何处理模数不互质的情况。 另外,用户可能希望了解如何识别题目是否适用CRT,例如当题目要求找到满足多个同余条件的最小解时,或者当模数不互质时需要扩展CRT。 最后,确保回答结构清晰,包括题目列表、解法要点、代码示例(如果有)以及相关练习建议。同时,生成相关问题,帮助用户进一步学习。</think>### Codeforces中国剩余定理相关题目及解法指南 --- #### **一、经典题目分类与解法** 以下题目均涉及中国剩余定理(CRT)或其扩展形式(exCRT),按难度排序: --- ##### **1. Codeforces 710D: Two Arithmetic Progressions (难度:2000)** **题目链接**: [710D](https://codeforces.com/contest/710/problem/D) **题意** 求区间 $[L, R]$ 内满足以下两个同余式的整数 $x$ 的数量: $$ \begin{cases} x \equiv a_1 \ (\text{mod} \ b_1) \\ x \equiv a_2 \ (\text{mod} \ b_2) \end{cases} $$ **解法要点** 1. **扩展中国剩余定理(exCRT)**:当模数 $b_1, b_2$ 不互质时,需合并两个同余式为单一方程。 2. **合并条件**:若合并后的方程无解,则答案为 $0$;否则计算解在区间内的分布[^3]。 3. **数学公式**: - 合并后的通解为 $x \equiv c \ (\text{mod} \ M)$,其中 $M = \text{lcm}(b_1, b_2)$。 - 区间内解的个数为 $\left\lfloor \frac{R - c}{M} \right\rfloor - \left\lfloor \frac{L - 1 - c}{M} \right\rfloor$。 **代码片段** ```cpp // 合并两个同余式 x ≡ a1 mod m1 和 x ≡ a2 mod m2 pair<long long, long long> merge(long long a1, long long m1, long long a2, long long m2) { long long g = gcd(m1, m2); if ((a2 - a1) % g != 0) return {-1, -1}; // 无解 long long lcm = m1 / g * m2; long long k = (a2 - a1) / g; long long x = (a1 + (k * inv(m1/g, m2/g)) % (m2/g) * m1) % lcm; return {x, lcm}; } ``` --- ##### **2. Codeforces 687B: Remainders Game (难度:1900)** **题目链接**: [687B](https://codeforces.com/contest/687/problem/B) **题意** 给定 $x \mod c_1, x \mod c_2, \dots, x \mod c_n$,判断是否能唯一确定 $x \mod k$。 **解法要点** 1. **CRT的核心条件**:若所有 $c_i$ 的最小公倍数 $\text{lcm}(c_1, c_2, \dots, c_n)$ 是 $k$ 的倍数,则可以唯一确定 $x \mod k$[^1]。 2. **直接计算**:计算 $\text{lcm}(c_1, c_2, \dots, c_n)$,检查是否 $\text{lcm} \mod k == 0$。 **代码逻辑** ```cpp long long lcm_all = 1; for (int ci : c) { lcm_all = lcm(lcm_all, ci); if (lcm_all > 1e12) break; // 防止溢出 } cout << (k % lcm_all == 0 ? "Yes" : "No") << endl; ``` --- ##### **3. Codeforces 1153C: Serval and Parenthesis Sequence (难度:1800)** **间接应用** 通过构造合法括号序列,隐含利用模运算平衡左右括号数量。需保证前缀和满足特定条件,类似同余约束[^4]。 --- #### **二、扩展中国剩余定理(exCRT)核心步骤** 当模数 **不互质** 时,标准CRT失效,需使用扩展方法: 1. **合并两个同余方程**: $$ \begin{cases} x \equiv a_1 \ (\text{mod} \ m_1) \\ x \equiv a_2 \ (\text{mod} \ m_2) \end{cases} $$ - 解方程 $a_1 + k_1 m_1 = a_2 + k_2 m_2$,即 $k_1 m_1 - k_2 m_2 = a_2 - a_1$。 - 使用扩展欧几里得算法求 $k_1, k_2$,若 $\gcd(m_1, m_2) \nmid (a_2 - a_1)$,则无解。 2. **递归合并**:将合并后的方程与下一个同余式继续合并,直至所有方程处理完毕。 --- #### **三、练习题目推荐** | 题目编号 | 难度 | 核心考点 | 链接 | |----------|------|----------|------| | **710D** | 2000 | exCRT与区间计数 | [Link](https://codeforces.com/contest/710/problem/D) | | **687B** | 1900 | CRT的存在性判定 | [Link](https://codeforces.com/contest/687/problem/B) | | **338D** | 2400 | exCRT与矩阵应用 | [Link](https://codeforces.com/problemset/problem/338/D) | --- #### **四、常见错误与调试技巧** 1. **溢出问题**:计算过程中需使用 `long long` 并随时取模。 2. **模数非互质**:忘记检查 $\gcd(m_i, m_j)$ 是否整除 $(a_j - a_i)$。 3. **区间端点处理**:计算区间内解的数量时,需注意边界条件(如 $x \geq L$ 且 $x \leq R$)。 --- #### **相关问题** 1. 如何判断两个同余方程是否可合并? 2. 扩展欧几里得算法在exCRT中如何具体应用? 3. 当模数极大时,如何优化CRT的计算过程?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值