中国剩余定理

中国剩余定理原理:

令某数为M,令素数为A,B,C,D,…,Z,已知M/A余a,M/B余b,M/C余c,M/D余d,…,M/Z余z。求M=?

因为A,B,C,D,…,Z为不同的素数,故,B*C*D*…*Z不可能被A整除,有等差数列(B*C*D*…*Z)+(B*C*D*…*Z)N中取A个连续项,这A个连续项分别除以A的余数必然存在0,1,2,3,…,A-1,所以,从这A个连续项中能寻找到除以A余1的数。再用除以A余1的这个数*a其积必然除以A余a,这个除以A余a的数,为能够被素数B*C*D*…*Z整除的数,为第一个数;

再按同样的道理,从A*C*D*…*Z的倍数中寻找除以B余b的数,该数具备被素数A,C,D,…,Z整除的特性,为第二个数;

因为,第一个数除以A余a,第二个数能被素数A,C,D,…,Z整除,即能被A整除,所以,第一个数+第二个数之和,仍然保持除以A余a;

同理,第二个数除以B余b,因第一个数能被B整除,所以,第二个数+第一个数之和,仍然保持除以B余b。即,第一个数+第二个数之和,为满足除以A余a,除以B余b。

依此类推,按上面的方法寻找到除以各素因子的余数的数之总和,为满足除以各素因子余数的条件的数。总和再减去能被这几个素数共同整除的数(A*B*C*D*…*Z)N后,其差仍然保持除以各素因子余数的条件的数。由此构成孙子定理的解法。

(中国剩余定理CRT)设m1,m2,...,mk是两两互素的正整数,即gcd(mi,mj) =1,i≠j,i,j = 1,2,...,k

则同余方程组:

x≡b1 (mod m1)

x≡b2 (mod m2)

...

x≡bk (mod mk)

模[m1,m2,...,mk]有唯一解,即在[m1,m2,...,mk]的意义下,存在唯一的x,满足:

x≡bi mod [m1,m2,...,mk],i = 1,2,...,k

折叠编辑本段证明方法

令T1=k1×m1,T2=k2×m2,T3=k3×m3;

因为 k1%a==1 ;所以 T1%a==m1;

对于 a,已知: T2%a==0,T3%a==0,T1%a==m1;

所以: Answer%a==m1;

因为:T1%b==0,T3%b==0,T2%b==m2 => Answer%b==m2

同理:Answer%c==m3;

又因为 a×b×c能同时整除 a b c,所以Answer ± P×(a×b×c)也是题目的解;

所以Answer是题目的解,又Answer = Answer % (a×b×c),所以Answer为最小解.

例题:

一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K。例如,K % 2 = 1, K % 3 = 2, K % 5 = 3。符合条件的最小的K = 23。
Input
第1行:1个数N表示后面输入的质数及模的数量。(2 <= N <= 10)
第2 - N + 1行,每行2个数P和M,中间用空格分隔,P是质数,M是K % P的结果。(2 <= P <= 100, 0 <= K < P)
Output
输出符合条件的最小的K。数据中所有K均小于10^9。
Input示例
3
2 1
3 2
5 3
Output示例
23
#include<iostream>
using namespace std;
int main() 
{
	int k,x;
	int i,j;
	long long m=1,sum=0,t;
	int a[102],b[102];
	scanf("%d",&k);
	for(i=0; i<k; i++) 
{
	scanf("%d%d",&a[i],&b[i]);
			m*=a[i];}
		for(i=0; i<k; i++) 
		{
			t=m/a[i];
			while(t%a[i]!=1) 
			{
				t+=m/a[i];
			}
			sum+=t*b[i];
		}
		x=sum%m;
	printf("%d\n",x);
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值