同余方程组的扩展欧几里得解法
2017-10-19 18:09
218 查看
同余方程组
mod.in/.out/.cpp
【问题描述】
求关于 x 的同余方程组
x%a 1 =b 1
x%a 2 =b 2
x%a 3 =b 3
x%a 4 =b 4
的大于等于 0 的最小整数解。
【输入格式】
一行 8 个整数,表示a 1 ,b 1 ,a 2 ,b 2 ,a 3 ,b 3 ,a 4 ,b 4 a1,b1,a2,b2,a3,b3,a4,b4 。
【输出格式】
一行一个整数,答案除以 p 的余数。
【样例输入】
2 0 3 1 5 0 7 3
【样例输出】
10
【数据规模和约定】
对于 30% 的数据,a i ai ≤ 40, 保证 a i ai 均为素数。
对于 60% 的数据,1≤a i ≤10 3 1≤ai≤103 , 保证a i ai 均互素。
对于 100% 的数据,0≤b i <a i ,1≤a i ≤10 3 0≤bi<ai,1≤ai≤103 。
【限制】
时间:1S
内存: 256M
数据前六十膜数互素,可以用CRT求解
不互素怎么办?用扩展欧几里得
x%a 1 =b 1
x%a 2 =b 2
x%a 3 =b 3
x%a 4 =b 4
显然可以变成
k1*a1+b1=x
k2*a2+b2=x
....
的形式
那么 k1*a1+b1=k2*a2+b2移项 => a1*k1-a2*k2=b1-b2
woc这不是ax+by=m么
因为a,b并不互素,显然该式在(a,b)即(a1,a2)不整除m的时候是无解的
此时可用扩展欧几里得求出一组特解x
通解是
X=x+k*lcm(a1,a2)
由上式可知 X%lcm(a1,a2)=x,两个方程由此合并
令 M=lcm(a1,a2) R=b2-b1
合并后的方程为 X mod M = R
那么合并n个方程就是按顺序来合并啦!即M=lcm(a1,a2,a3.....)
那么上代码 其中数组m表示a,数组r表示b
mod.in/.out/.cpp
【问题描述】
求关于 x 的同余方程组
x%a 1 =b 1
x%a 2 =b 2
x%a 3 =b 3
x%a 4 =b 4
的大于等于 0 的最小整数解。
【输入格式】
一行 8 个整数,表示a 1 ,b 1 ,a 2 ,b 2 ,a 3 ,b 3 ,a 4 ,b 4 a1,b1,a2,b2,a3,b3,a4,b4 。
【输出格式】
一行一个整数,答案除以 p 的余数。
【样例输入】
2 0 3 1 5 0 7 3
【样例输出】
10
【数据规模和约定】
对于 30% 的数据,a i ai ≤ 40, 保证 a i ai 均为素数。
对于 60% 的数据,1≤a i ≤10 3 1≤ai≤103 , 保证a i ai 均互素。
对于 100% 的数据,0≤b i <a i ,1≤a i ≤10 3 0≤bi<ai,1≤ai≤103 。
【限制】
时间:1S
内存: 256M
数据前六十膜数互素,可以用CRT求解
不互素怎么办?用扩展欧几里得
x%a 1 =b 1
x%a 2 =b 2
x%a 3 =b 3
x%a 4 =b 4
显然可以变成
k1*a1+b1=x
k2*a2+b2=x
....
的形式
那么 k1*a1+b1=k2*a2+b2移项 => a1*k1-a2*k2=b1-b2
woc这不是ax+by=m么
因为a,b并不互素,显然该式在(a,b)即(a1,a2)不整除m的时候是无解的
此时可用扩展欧几里得求出一组特解x
通解是
X=x+k*lcm(a1,a2)
由上式可知 X%lcm(a1,a2)=x,两个方程由此合并
令 M=lcm(a1,a2) R=b2-b1
合并后的方程为 X mod M = R
那么合并n个方程就是按顺序来合并啦!即M=lcm(a1,a2,a3.....)
那么上代码 其中数组m表示a,数组r表示b
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define LL long long LL a[6],r[6]; int n; LL exgcd(LL a,LL b,LL &x,LL &y) { if(b==0) {x=1,y=0;return a;} LL tmp=exgcd(b,a%b,y,x); y-=a/b*x; return tmp; } LL solve() { LL M=a[1],R=r[1],x,y,d; for(int i=2;i<=4;i++) { d=exgcd(M,a[i],x,y); if((R-r[i])%d!=0) return -1; x=(R-r[i])/d*x%a[i]; R-=x*M; M=M/d*a[i]; R%=M; } return (R%M+M)%M; } int main() { for(int i=1; i<=4; i++) scanf("%lld%lld",&a[i],&r[i]); printf("%lld\n",solve()); return 0; }
相关文章推荐
- 同余方程——扩展欧几里得の板子
- 【NOIP 2012 Day2 T1】同余方程(扩展欧几里得)
- poj 1061 扩展欧几里得求解同余方程
- 同余方程(扩展欧几里得)
- 【扩展欧几里得】Codevs 1200: [noip2012]同余方程
- 青蛙的约会(扩展欧几里得解同余方程)
- 扩展欧几里得模板(洛谷1082 同余方程NOIP 2012 提高组 第二天 第一题)
- 扩展欧几里得详解 NOIP2012同余方程 青蛙的约会
- 乘法逆元的扩展欧几里得解法
- Noip2012 Day2 T1 同余方程(扩展欧几里得)
- exgcd扩展欧几里得--noip同余方程
- 扩展欧几里得、同余方程学习
- POJ 2891 & 2018多校练习赛(第三场)-B(扩展欧几里得解同余方程组)
- POJ 2115 扩展欧几里得解最基本的同余方程
- 【扩展欧几里得】Codevs 1200: [noip2012]同余方程
- 洛谷Oj-P1082 同余方程-扩展欧几里得
- 【扩展欧几里得】NOIP2012同余方程
- noip2012 同余方程 (扩展欧几里得)
- [luoguP1082] 同余方程(扩展欧几里得)
- POJ - 1601 - 青蛙的约会 - (扩展欧几里得解同余方程)