中国剩余定理解法

问题表述
 
《孙子算经》卷下第二十六问:“今有物,不知其数。三、三数之,剩二;五、五数之,剩三;七、七数之,剩二。问物几何?答曰:二十三。”

即 x%3=2;x%5=3;x%7=2;  》》  x=23+3*5*7*k

表述成定理为:
给m个两两互质的数,其乘积为P,若已知x<P,且知x与这m个数的模,则x唯一确定。

以m=2为例,设为a,b,令x=1~a*b;
x mod a 的结果为 (0,1,...,a-1) 的循环;
x mod b 的结果为 (0,1,...,b-1) 的循环;
则(x%a, x%b)的循环周期为P=a*b, 在P范围内,是唯一确定的。
 
 
问题求解
m=3,分别为a,b,c,如何求x?
brute-force:
     求出P内满足条件 i (x%ai=ci) 的x的集合,求交。
clever:
     构造出一个满足条件的x,不必小于P,x%P即为所求。具体的,构造t1为ab的倍数,且模c等于x模c,同理构造出t2,t3,则 x=(t1+t2+t3)%P。

这引出了下一个问题:a*x % b = c ,求x?
     事实上,只有当a与b互质,方程有解;因为其等价于 X=a*x,X%a=0,X%b=c,由中国剩余定理可知其有解。if (a*x)% b= 1, (a*c*x)%b = c,因此也等价于求 (a*x)% b= 1 。
     即求解 a的多少倍 - b的多少倍 = 1,用扩展的辗转相除法。
     如a=5,b=7:
          7/5 = 1 ...2,(5,7) 的系数为 (1,1),剩下 5,2
          5/2 = 2 ...1,(5,2) 的系数为 (1,2),于是(5,7)的系数为(3,2)
          5*3 - 7*2 = 1,求得 x = 3。
     该扩展辗转相除法还是相当精妙的!

     若 a和b的最大公约数d不为1,则只能求解 a*x % b = d 。
 
参考:Matrix67大牛的博文 ---“跨越千年的RSA算法
 
 
代码实现
 
python写的代码,从上述思路到实现还是有一定距离的,^ ^
# solve a*x % b = c ;
# a and b are co-prime ;
# solve it equals to a*x % b = 1 ,
# cause if (a*x)% b= 1, (a*c*x)%b = c

def example():
    a = 115
    b = 367
    c = 2
    for i in range(1,20):
        print (a*i%b)

# GCD(a,b) should be 1
def extra_divide(a,b,c):
    if not c<b:
        print 'b should be greater than c'
        return -1
    # assume a > b
    aa = a
    bb = b
    exchanged = False
    if a<b:
        exchanged = True
        t = a
        a = b
        b = t
    
    rec_array = []
    
    r = 0
    while r!=1:
        r = a%b
        d = a/b
        rec_array.append( 1 )
        rec_array.append( d )

        a = b
        b = r

    #print rec_array

    # this is the most important part, take 25,7 for example
    # 25 % 7, 7 % 4, 4 % 3
    #  1   3, 1   1, 1   1;  one 3 equals one 7 and one 4, so
    #  1   3, 1   2;         two 4 equals two 25 and six 7, so
    #  2   7;
    
    
    for i in range(0,len(rec_array)-2,2):
        j = len(rec_array) - i - 1
        rec_array[j-2] *= rec_array[j]
        rec_array[j-3] *= rec_array[j]
        rec_array[j-2] += rec_array[j-1]
    k1 = rec_array[0]
    k2 = rec_array[1]

    if exchanged:
        t = k1
        k1 = k2
        k2 = t
    
    # we want ax%b=1, now b%(ax)=1, so play a magic here
    # k1*a + 1 = k2*b, also b*a = a*b, take a difference
    # we get (b-k1)*a -1 = (a-k2)*b, bingo!
    if aa*k1 < bb*k2:
        k1 = bb-k1
        k2 = aa-k2

    print 'x='+str(k1), 'a*x='+str(k1*aa), 'b*y='+str(k2*bb)

## test
extra_divide(7,5,1)
extra_divide(25,7,1)
extra_divide(115,367,1)
extra_divide(367,115,1)
extra_divide(128,367,1)




安装.NET Framework失败后上网找的卸载工具,亲测卸载后可以完成安装.NET Framework。 一下位介绍: ====================== 分享可以完美卸载.NET Framework 1.0~4.5的framework卸载工具。.NET Framework几乎是系统比不可少的运行组件,特别是现在越来越多的软件都需要.NET Framework运行库的支持。例如本站给大家分享的coreldraw x6安装程序,就必须要.NET Framework 3.5、.NET Fra...... yinshu 分享可以完美卸载.NET Framework 1.0~4.5的framework卸载工具。.NET Framework几乎是系统比不可少的运行组件,特别是现在越来越多的软件都需要.NET Framework运行库的支持。例如本站给大家分享的coreldraw x6安装程序,就必须要.NET Framework 3.5、.NET Framework 4.0运行库的支持才可以安装及运行。 但最近有一台电脑,.NET Framework 4.0死活安装不上(可能是以前不完整安装造成的),想把Framework卸载了重新安装,结果系统自带的卸载工具还卸载不了,甚是头疼,后来找到这款专业的.net framework卸载工具:cleanup_tool才终于把net framework请出电脑,然后再次安装.NET Framework 4.0成功。 NET Framework卸载工具 .NET Framework Cleanup Tool软件简介 .NET Framework Cleanup Tool是一个专用于卸载、清除掉计算机中不同版本.NET框架的免费小软件。支持所有语言的.NET。它能删除与.NET相关的文件,并且还能自动将对应的文件夹、注册表项目和Windows Installer文件全部删除。 使用.NET Framework Cleanup Tool,基本可以将电脑还原到未安装.NET框架时的状态。因此,当你发现.NET不能正常更新,或是无法删除、甚至于重新安装不起作用时,试试这个小软件。 如何卸载framework cleanup_tool支持.NET Framework 1.0~4.5卸载,虽然是英文版的,不过使用简单,只要运行后选择你需要清除的.net framework版本(或者选择卸载全部.NET Framework版本),然后点击“cleanup now”按钮即可开始执行清除作业,过程会持续一到两分钟即可完成framework卸载。 特别注意:net framework框架并不是无用的东西,现在很多程序都需要net framework环境才能运行,所以建议你只有当.NET Framework损坏或者安装不上新版本时才考虑卸载重装。
<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、付费专栏及课程。

余额充值