poj 2891 扩展欧几里得迭代解同余方程组
Reference: http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html
之前说过中国剩余定理传统解法的条件是m[i]两两互质,所以这题就不能用传统解法了= =
其实还有种方法:
先来看只有两个式子的方程组:
c≡b1 (mod a1)
c≡b2 (mod a2)
变形得c=a1*x+b1,c=a2*x+b2
a1*x-a2*y=b2-b1
可以用扩展欧几里得求出x和y,进而求出c
那么多个式子呢?可以两个两个的迭代求。
比如上面两个式子求完了,求出一个c,不妨先把它记作c1
c1满足上面两式,但对于所有的式子就不一定都满足了。
因此我们把一个新同余式加入方程组:c≡c1 (mod lcm(a1,a2)) //lcm为最小公倍数
然后依次往下迭代就行了。最后解出的c1就是最终解。
如何判断无解?
对于相邻的两行a1、a2、r1、r2,若 (r2-r1) mod (gcd(a1,a2))!=0说明无解
- #include "iostream"
- using namespace std;
- __int64 a[];
- __int64 r[];
- int n;
- __int64 extend_gcd(__int64 a,__int64 b,__int64 &x,__int64 &y){
- if (b==){
- x=;y=;
- return a;
- }
- else{
- __int64 r=extend_gcd(b,a%b,y,x);
- y=y-x*(a/b);
- return r;
- }
- }
- __int64 gcd(__int64 a,__int64 b)
- {
- if (b==) return a;
- return gcd(b,a%b);
- }
- __int64 lcm(__int64 a,__int64 b)
- {
- __int64 tm=gcd(a,b);
- if (tm==) return ;
- else return (a*b/tm);
- }
- int main()
- {
- while (cin>>n)
- {
- for (int i=;i<=n;i++)
- cin>>a[i]>>r[i];
- __int64 x,y,x1,c1;
- bool sol=true;
- for (int i=;i<=n;i++)
- {
- __int64 a1=a[i-],r1=r[i-];
- __int64 a2=a[i],r2=r[i];
- __int64 tmp=gcd(a1,a2);
- if ((r2-r1)%tmp!=) sol=false; //此处有个问题= =原来我是这样写的,WA了
- __int64 tm=extend_gcd(a1,a2,x,y); //__int64 tm=extend_gcd(a1,-a2,x,y)
- x1=x*((r2-r1)/tm); //but the original equation is a1*x1-a2*x2=b2-b1
- __int64 rq=a2/tm; //__int64 rq=-a2/tm
- x1=(x1%rq+rq)%rq; //去掉a2的负号就A了,What a fuck!!!
- //个人猜想是因为gcd(a,b)和gcd(a,-b)结果是一样的,
- //而且此处需要的是非负解,结果就YY对了
- c1=a1*x1+r1;
- r[i]=c1;
- a[i]=lcm(a1,a2);
- // cout<<r[i]<<" "<<a[i]<<endl;
- }
- //cout<<c1<<endl;
- __int64 ans=c1;
- if (!sol) cout<<"-1"<<endl;
- else cout<<ans<<endl;
- }
- return ;
- }
至于负号那个地方有个题hdu 1576,和本题一个情况。把负号YY掉就对了= =
poj 2891 扩展欧几里得迭代解同余方程组的更多相关文章
- POJ 2891 Strange Way to Express Integers | exGcd解同余方程组
题面就是让你解同余方程组(模数不互质) 题解: 先考虑一下两个方程 x=r1 mod(m1) x=r2 mod (m2) 去掉mod x=r1+m1y1 ......1 x=r2+m2y2 . ...
- poj 2142 扩展欧几里得解ax+by=c
原题实际上就是求方程a*x+b*y=d的一个特解,要求这个特解满足|x|+|y|最小 套模式+一点YY就行了 总结一下这类问题的解法: 对于方程ax+by=c 设tm=gcd(a,b) 先用扩展欧几里 ...
- poj 1061 扩展欧几里得解同余方程(求最小非负整数解)
题目可以转化成求关于t的同余方程的最小非负数解: x+m*t≡y+n*t (mod L) 该方程又可以转化成: k*L+(n-m)*t=x-y 利用扩展欧几里得可以解决这个问题: eg:对于方程ax+ ...
- poj 1061(扩展欧几里得定理求不定方程)
两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特 ...
- 扩展欧几里得(exgcd)与同余详解
exgcd入门以及同余基础 gcd,欧几里得的智慧结晶,信息竞赛的重要算法,数论的...(编不下去了 讲exgcd之前,我们先普及一下同余的性质: 若,那么 若,,且p1,p2互质, 有了这三个式子, ...
- poj 2115 扩展欧几里得
题目链接:http://poj.org/problem?id=2115 题意: 给出一段循环程序,循环体变量初始值为 a,结束不等于 b ,步长为 c,看要循环多少次,其中运算限制在 k位:死循环输出 ...
- The Balance POJ 2142 扩展欧几里得
Description Ms. Iyo Kiffa-Australis has a balance and only two kinds of weights to measure a dose of ...
- POJ 1061 扩展欧几里得
#include<stdio.h> #include<string.h> typedef long long ll; void gcd(ll a,ll b,ll& d, ...
- 扩展欧几里得,解线性同余方程 逆元 poj1845
定理:对于任意整数a,b存在一堆整数x,y,满足ax+by=gcd(a,b) int exgcd(int a,int b,int &x,int &y){ ){x=,y=;return ...
随机推荐
- 发布资源到Asset Store
导入unitypackage右上角没有图标? 每当导入从Asset Store下载的资源时,总会看到右侧有个ICON 而我们自己导出的*.unitypackage ,当我们再次导入时,在右侧就没有此图 ...
- 一个完整的JENKINS下的ANT BUILD.XML文件
网上看见的,确实很全,该有的基本都覆盖到了.自己拿来稍微改改就可以用了. 注:property中的value是你自己的一些本地变量.需要改成自己的 <?xml version="1.0 ...
- git rebase 介绍
git rebase是对commit history的改写.当你要改写的commit history还没有被提交到远程repo的时候,也就是说,还没有与他人共享之前,commit history是你私 ...
- Spring中使用Quartz
package com.ncs.hj; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; ...
- ssh scp 复制文件和文件夹
三,复制文件或目录命令: 复制文件: (1)将本地文件拷贝到远程 scp 文件名用户名@计算机IP或者计算机名称:远程路径 本地192.168.1.8客户端 scp /root/install ...
- JS自定义事件之选项卡
自定义事件是一种处理与DOM产生交互的代码逻辑片段之间耦合的很好的架构方法. 一个简单的jQuery插件——选项卡 让ul列表来响应点击事件.当用户点击一个列表项时,给这个列表项添加一个名为activ ...
- php基础33:正则匹配-perl
<?php //1.搜索数组中的相匹配的字符串 //preg_grep() 返回一个数组 $language = array("php","asp",&q ...
- Linux常用指令---工作
查看所有用户cat /etc/passwd 复制整个目录cp -ri A/B/* A1/B1/ 若复制过程中询问是否覆盖,输入y按回车 另外若A A1不在同一目录下,最好填绝对路径,就是/xxx/xx ...
- [CareerCup] 12.2 Find the Reason of Crash 找到程序崩溃的原因
12.2 You are given the source to an application which crashes when it is run. After running it ten t ...
- C#中out和ref之间的区别
首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:rel可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所 ...