【poj2891】同余方程组

同余方程组

例题1pku2891Strange Way to Express Integers

中国剩余定理求的同余方程组mod 的数是两两互素的。然而本题(一般情况,也包括两两互素的情况,所以中国剩余定理成为了“时代的眼泪”)mod的数可能不是互素,所以要转换一下再求。

P=b1(mod a1);  P / a1 ==?~~~~b1

P =b2(mod a2);

P =b3(mod a3);

……

P =bn(mod an);

a1~an,b1~bn是给出来的。

解:

第一条:a1*x+b1= P

第二条:a2*y+b2= P

第一条减去第二条: a1*x - a2*y = b2-b1

设A=a1,B=-a2,K=b2-b1,得到了x(实际调用exgcd的时候不理会a2前面的负号)

如果K%d!=0,无解

否则,X=[ (x* K/d)%(B/d)+(B/d) ]%(B/d)

LCU表示最小公倍数

P= a1*X+b1+ 若干倍的LCU(a1,a2)(或者把Y=(K-AX)/B,再P=a2*Y+b2+ 若干倍的LCU(a1,a2)

所以新的b= a1*x+b1,新的a= LCU(a1,a2),

把新的b当成b1,新的a当成a1,再去和a3和b3结合,一直到最后结束,最后新的b就是X

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<cmath>
 7 using namespace std;
 8 #define LL long long
 9
10 LL a1,b1,a2,b2;
11
12 LL ax,ay;
13 LL exgcd(LL a,LL b)
14 {
15     if(b==0) {ax=1,ay=0;return a;}
16     LL g=exgcd(b,a%b);
17     LL yy=ay;
18     ay=ax-a/b*ay;ax=yy;
19     return g;
20 }
21
22 int main()
23 {
24     freopen("a.in","r",stdin);
25     freopen("a.out","w",stdout);
26     int n;
27     while(scanf("%d",&n)!=EOF)
28     {
29         scanf("%lld%lld",&a1,&b1);
30         bool ok=1;
31         for(int i=2;i<=n;i++)
32         {
33             scanf("%lld%lld",&a2,&b2);
34             if(!ok) continue;
35             LL a,b,c,g;
36             a=a1,b=a2,c=b2-b1;
37             g=exgcd(a,b);
38             if(c%g!=0) {ok=0;continue;}
39             if(b/g<0) b*=-1;
40             ax=((ax*c/g)%(b/g)+(b/g))%(b/g);
41             a=b1+ax*a1;
42             g=a1*a2/exgcd(a1,a2);
43             a1=g;b1=a;
44         }
45         if(!ok) printf("-1\n");
46         else printf("%lld\n",b1);
47     }
48     return 0;
49 }

【poj2891】

2016-02-02 09:44:06

时间: 2024-08-01 15:17:56

【poj2891】同余方程组的相关文章

数论之拓展欧几里得求解不定方程和同余方程组(一)

今天接到scy的压缩包,开始做数论专题.那今天就总结一下拓展欧几里得求解不定方程和同余方程组. 首先我们复习一下欧几里得算法: 1 int gcd(int a,int b){ 2 if(b==0) return a; 3 return gcd(b,a%b);4 } 拓展欧几里得算法: 推导过程: 给出A和B,求它们的最大公约数,并且求出x和y,满足Ax+By=gcd(A,B). 当A=0时,x=0,y=1; 当A>0时, 因为exgcd(A,B,x,y)表示Ax+By=gcd(A,B) 而且ex

再说中国剩余定理、扩展欧几里德和同余方程组

E - 解同余线性方程组1 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Andy和Mary养了很多猪.他们想要给猪安家.但是Andy没有足够的猪圈,很多猪只能够在一个猪圈安家.举个例子,假如有16头猪,Andy建了3个猪圈,为了保证公平,剩下1头猪就没有地方安家了.Mary生气了,骂Andy没有脑子,并让他重新建立猪圈.这回Andy建造

解一元同余方程组

2016.1.26 试题描述 给定n个一次同余方程x mod mi=ai,这里i=0,1,2,……,n-1,给定数据保证所有的mi两两互素.求该方程组的解. 输入 第一行包含一个正整数n,接下来的n行,每行包括两个整数,对应一个同余方程,第一个数为mi,第二个数为ai,两数间用一个空格分隔. 输出 一个数,表示方程组的解. 输入示例 33 25 37 2 输出示例 23 其他说明 数据范围:所有给定的数据均在int32范围内,且保证所有的数据都符合题目描述的要求,结果在long long范围内.

线性同余方程组

线性同余方程组就是由多个线性同余方程联立得到的.用数学符号表示就是求解ai*x≡bi(mod m)(1≤i≤n)这样的方程. 可知解的全集一定可以写成x≡b(mod m)的形式,因此我们只要对所有线性同余方程依次求解即可. 因为x≡b1(mod m1),所以将x写成x=b1+m1*t并代入第二个式子,可得 a(b1+m1*t)≡b2(mod m2) 整理得 a*m1*t≡b2-a*b1(mod m2) 然后求解这个一次同余方程即可.当gcd(m2,a*m1)无法整除b2-a*b1时原方程组无解.

解线性同余方程组

想必学完exgcd的各位dalao们都已经明白如何求解同余方程了 今天本蒟蒻只是想讲讲线性同余方程组的解法供各位大佬批评指错 我们现在有一些线性同余方程 X=b1 (mod a1) X=b2 (mod a2) ... X=bn (mod an) 对于前面第一个方程,我们可以用exgcd求出一个X满足一式 不妨设X=a1*y1+b1 若存在X满足二式,则a1*y1+b1=b2 (mod a2) 所以y1=(b2-b1)/a1 (mod a2) 该式有解当且仅当(b2-b1)|gcd(a1,a2)

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

如果模数互质的话,直接中国剩余定理就可以了 但是如果模数不互质又没有接触这个方法就凉凉了 推是很不好推出来的 假设我们这里有两个方程: x=a1?x1+b1 x=a2?x2+b2 a1,a2是模数,b1,b2是余数 那么我们可以合并这两个方程: a1?x1+b1=a2?x2+b2 由于x1和x2可以取负无穷到正无穷,所以符号不能约束它们,我们随便变一变形得到 a1?x1+a2?x2=b2?b1 然后使用拓展欧几里德算法,x和y分别是式子中的x1和x2 我们求出了一个最小正整数解x1 令k=(a1

HDU-3579-Hello Kiki (利用拓展欧几里得求同余方程组)

设 ans 为满足前 n - 1个同余方程的解,lcm是前n - 1个同余方程模的最小公倍数,求前n个同余方程组的解的过程如下: ①设lcm * x + ans为前n个同余方程组的解,lcm * x + ans一定能满足前n - 1个同余方程: ②第 n 个同余方程可以转化为a[n] * y + b; 合并①②得:lcm * x + ans = a[n] * y + b; => lcm * x - a[n] * y = b - ans(可以用拓展欧几里得求解x和y) 但是拓展欧几里得要求取余的数

【hdu1573-X问题】拓展欧几里得-同余方程组

http://acm.hdu.edu.cn/showproblem.php?pid=1573 求小于等于N的正整数中有多少个X满足: X mod a0 = b0 X mod a1 = b1 …… X mod ai = bi (0<ai<=10) 输入:第一行为一个正整数T,表示有T组测试数据.每组测试数据的第一行为两个正整数N,M (0 < N <= 1000,000,000 , 0 < M <= 10),表示X小于等于N,数组a和b中各有M个元素.接下来两行,每行各有

【hdu3579-Hello Kiki】拓展欧几里得-同余方程组

http://acm.hdu.edu.cn/showproblem.php?pid=3579 题解:同余方程组的裸题.注意输出是最小的正整数,不包括0. #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; typedef long long LL; const int N=20; LL exgcd(LL a,LL b,LL &