码迷,mamicode.com
首页 > 其他好文 > 详细

拓展中国剩余定理解决模数不互质同余方程组

时间:2018-08-15 21:04:08      阅读:577      评论:0      收藏:0      [点我收藏+]

标签:正整数   lld   msu   class   row   col   name   main   变形   

如果模数互质的话,直接中国剩余定理就可以了

但是如果模数不互质又没有接触这个方法就凉凉了

推是很不好推出来的

假设我们这里有两个方程: 

x=a1?x1+b1

x=a2?x2+b2 

a1,a2是模数,b1,b2是余数

那么我们可以合并这两个方程:

a1?x1+b1=a2?x2+b2

由于x1x2可以取负无穷到正无穷,所以符号不能约束它们,我们随便变一变形得到

a1?x1+a2?x2=b2?b1

然后使用拓展欧几里德算法,x和y分别是式子中的x1和x2

我们求出了一个最小正整数解x1

k=(a1?x1+b1)

xk(mod lcm(a1,a2))

一路合并下去就可以得到最终的解答了

典型例题是POJ2891,全网仅此一道??

POJ真是交上去立刻A

 1 #include<cstdio>
 2 using namespace std;
 3 const int maxn=100005;
 4 int n;
 5 long long a[maxn],m[maxn];
 6 long long exgcd(long long a,long long b,long long &x,long long &y)
 7 {
 8     if(b==0) {x=1;y=0;return a;}
 9     long long ret=exgcd(b,a%b,x,y);
10     long long t=x;x=y;y=t-a/b*y;
11     return ret;
12 }
13 long long crt()
14 {
15     long long M=m[1],A=a[1];
16     long long x,y;
17     for(int i=2;i<=n;i++)
18     {
19         long long d=exgcd(M,m[i],x,y);
20         if((a[i]-A)%d) return -1;  //无解
21         //计算x的值 
22         x*=(a[i]-A)/d;
23         long long t=m[i]/d;
24         x=(x%t+t)%t;
25         A=M*x+A;
26         M=M/d*m[i];
27         A%=M; 
28     }
29     A=(A%M+M)%M;
30     return A;
31 }
32 int main()
33 {
34     while(scanf("%d",&n)==1)
35     {
36         for(int i=1;i<=n;i++)
37             scanf("%lld%lld",&m[i],&a[i]);
38         printf("%lld\n",crt());
39     }
40     return 0;
41 }

 

拓展中国剩余定理解决模数不互质同余方程组

标签:正整数   lld   msu   class   row   col   name   main   变形   

原文地址:https://www.cnblogs.com/aininot260/p/9483902.html

(1)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!