POJ 2891 扩展欧几里德
这个题乍一看跟剩余定理似的,但是它不满足两两互素的条件,所以不能用剩余定理,也是给了一组同余方程,找出一个X满足这些方程,如果找不到的话就输出-1
因为它不满足互素的条件,所以两个两个的合并,最后合成一个。
题目给定的是
M % m1 = r1
M % m2 = r2
......
M % mn = rn
只需将两个式子合并成一个式子,那么这个合并的这个式子就可以继续和下面的式子继续合并,知道合到最后一个式子。
首先来看下两个式子怎么合并。
M % m1 = r1 可以写成 M = k1 * m1 + r1;
同理M = k2 * m2 + r2
所以k1 * m1 + r1 = k2 * m2 + r2
k1 * m1 - k2 * m2 = r2 - r1
将k1 看成x, m1看成a, k2看成y, m2看成b, r2 - r1看成c
那么这个式子就变成了
ax-by=c;不定方程
这时候就可以用不定方程来解了。
因为题目给的两两可能不互素,所以gcd(a, b) 有可能不等于1,所以,这个方程不一定有解,所以就是判断这个题有没有解的条件。
如果有解的话,用扩展欧几里德可以的出这个方程的解,然后将x带入到 k1 * m1 + r1中得到M,这时候M就是这两个方程组的一个特解,通解就是M' = M + K * LCM(m1, m2);
这个式子可以变化成M' % LCM(m1, m2) = M;所以又可以继续跟下面的式子合并了。所以这个式子对应的余数r就是M, 模数(就是式子中的mi)就是LCM(m1,m2);
到这里之后就合并好了一个式子。下面就是继续按照这个过程合并到第n个式子了。最后合并完之后就剩下一个式子,求出来的M就是方程组的特解,通解为M' = M + k * LCM; 其中LCM = LCM(m1, m2...mn), 最小正整数解为(M % LCM + LCM) % LCM;
还有一个坑就是如果边输入边处理的话,不要找到无解立马就跳出循环,因为后面的数据还没输入完。
代码如下:
/*************************************************************************
> File Name: 5.cpp
> Author: Howe Young
> Mail: 1013410795@qq.com
> Created Time: 2015年08月01日 星期六 15时39分47秒
************************************************************************/ #include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + ;
typedef long long ll;
ll m[maxn], r[maxn];
ll exgcd(ll a, ll b, ll &x, ll &y)
{
if (b == )
{
x = ;
y = ;
return a;
}
ll r = exgcd(b, a % b, x, y);
ll t = x;
x = y;
y = t - a / b * y;
return r;
}
int main()
{
int k;
while (~scanf("%d", &k))
{
for (int i = ; i <= k; i++)
scanf("%lld %lld", &m[i], &r[i]);
ll m1, m2, r1, r2, c, d;
m1 = m[]; r1 = r[];
bool flag = true;
for (int i = ; i <= k; i++)
{
ll x, y;
d = exgcd(m1, m[i], x, y);
if ((r[i] - r1) % d != )
{
flag = false;
break;
}
c = r[i] - r1;
x = c / d * x % (m[i] / d);
r1 = m1 * x + r1;
m1 = m1 / d * m[i];
r1 %= m1;
}
if (!flag)
{
printf("-1\n");
continue;
}
r1 = (r1 + m1) % m1;
printf("%lld\n", r1);
} return ;
}
POJ 2891 扩展欧几里德的更多相关文章
- poj 2891 扩展欧几里得迭代解同余方程组
Reference: http://www.cnblogs.com/ka200812/archive/2011/09/02/2164404.html 之前说过中国剩余定理传统解法的条件是m[i]两两互 ...
- poj 1061 扩展欧几里德同余方程求解
摘要写在一瞪眼. #include<iostream> using namespace std; long long exgcd(long long a,long long b,long ...
- poj 2115 扩展欧几里德
#include<stdio.h> #include<string.h> #define max 32 typedef long long LL; LL pow2[max+]; ...
- POJ - 1061 扩展欧几里德算法+求最小正整数解
//#pragma comment(linker, "/STACK:1024000000,1024000000") //#pragma GCC optimize(2) #inclu ...
- 数学#扩展欧几里德 POJ 1061&2115&2891
寒假做的题了,先贴那时写的代码. POJ 1061 #include<iostream> #include<cstdio> typedef long long LL; usin ...
- 扩展欧几里德 POJ 1061
欧几里德的是来求最大公约数的,扩展欧几里德,基于欧几里德实现了一种扩展,是用来在已知a, b求解一组x,y使得ax+by = Gcd(a, b) =d(解一定存在,根据数论中的相关定理,证明是用裴蜀定 ...
- poj 1061 青蛙约会(扩展欧几里德)
题目链接: http://poj.org/problem?id=1061 题目大意: 中文题目,题意一目了然,就是数据范围大的出奇. 解题思路: 假设两只青蛙都跳了T次,可以列出来不定方程:p*l + ...
- POJ 2142 The Balance【扩展欧几里德】
题意:有两种类型的砝码,每种的砝码质量a和b给你,现在要求称出质量为c的物品,要求a的数量x和b的数量y最小,以及x+y的值最小. 用扩展欧几里德求ax+by=c,求出ax+by=1的一组通解,求出当 ...
- POJ 1061 青蛙的约会(扩展欧几里德)
点我看题目 题意 : 中文题不详述. 思路 : 设经过s步后两青蛙相遇,则必满足(x+m*s)-(y+n*s) = K*L(k = 0,1,2....) 变形得:(n-m)*s+K*L = x-y ; ...
随机推荐
- MongoDB 复制集模式Replica Sets
1.概述 复制集是一个带有故障转移的主从集群.是从现有的主从模式演变而来,增加了自动故障转移和节点成员自动恢复. 复制集模式中没有固定的主结点,在启动后,多个服务节点间将自动选举 产生一个主结点.该主 ...
- WAMP学习日记之:Apache发布php网站
1.修改httpd.conf 文件,以便让Apache和php模块建立关联 2.配置php.ini文件 修改httpd.conf 文件,以便让Apache和php模块建立关联 如何让apache和ph ...
- LCD驱动学习笔记
通过这几天的学习发现驱动的框架感觉都差不多,一般分为以下几个步骤: 分配一个结构体 struct x *x = amlloc(); 设置结构体的参数 硬件寄存器 file_operations 注册 ...
- html5桌面通知,notification的使用,右下角出现通知框
1先判断浏览器是否支持:window.Notification 2判断浏览器是否开启提示的权限:Notification.permission === 'granted'(如果不允许则设置为允许:No ...
- JSP页面的异常处理<转>
对于jsp页面错误处理这里大致有两种方式:一.在Web.xml中配置全局的错误异常处理 即凡是该项目下(即虚拟路径下的所有文件)的任意一个文件错误或者异常,都会跳到指定的错误处理页面. ...
- Delphi文件映射
http://www.cnblogs.com/key-ok/p/3429860.htmlhttp://www.cnblogs.com/key-ok/p/3380793.htmlhttp://www.c ...
- 【HDOJ】2364 Escape
bfs.题目做的不细心,好多小错误.尤其注意起始点就是边界的情况.wa了八次. #include <iostream> #include <cstdio> #include & ...
- BZOJ1679: [Usaco2005 Jan]Moo Volume 牛的呼声
1679: [Usaco2005 Jan]Moo Volume 牛的呼声 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 723 Solved: 346[ ...
- 数据结构(线段树):NOI 2016 区间
[问题描述] [输入格式] [输出格式] [样例输入] 6 3 3 5 1 2 3 4 2 2 1 5 1 4 [样例输出] 2 [样例说明] [更多样例] 下载 [样例 2 输入输出] 见目录下的 ...
- QTP自传之描述性编程
描述性编程,即采用描述性的语言定位对象,不需要事先将对象添加到对象库中.下面,就说说如何使用描述性编程,我们将继续使用对象库编程中的网页. 使用描述性编程的两种方法 直接描述 对象("属性名 ...