博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数论 线性同余方程的应用 poj2891
阅读量:6142 次
发布时间:2019-06-21

本文共 2439 字,大约阅读时间需要 8 分钟。

Strange Way to Express Integers
Time Limit: 1000MS   Memory Limit: 131072K
Total Submissions: 17321   Accepted: 5828

Description

 

Elina is reading a book written by Rujia Liu, which introduces a strange way to express non-negative integers. The way is described as following:

 

Choose k different positive integers a1a2…, ak. For some non-negative m, divide it by every ai (1 ≤ i ≤ k) to find the remainder ri. If a1a2, …, ak are properly chosen, m can be determined, then the pairs (airi) can be used to express m.

“It is easy to calculate the pairs from m, ” said Elina. “But how can I find m from the pairs?”

Since Elina is new to programming, this problem is too difficult for her. Can you help her?

Input

The input contains multiple test cases. Each test cases consists of some lines.

  • Line 1: Contains the integer k.
  • Lines 2 ~ k + 1: Each contains a pair of integers airi (1 ≤ i ≤ k).

 

Output

Output the non-negative integer m on a separate line for each test case. If there are multiple possible values, output the smallest one. If there are no possible values, output -1.

 

Sample Input

28 711 9

Sample Output

31

解同于方程组:

xr1(moda1)
xr2(moda2)
......
xrn(modan)
其中模数不一定互质。

 

题解

若模数两两互质,我们可以用中国剩余定理来解。 

这里我们先考虑两个方程:

    xr1(moda1)
    xr2(moda2)
我们可以写成:
     x+y1a1=r1
     xy2a2=r2
相减得:y1a1+y2a2=r1−r2也就是ax+by=m的形式。 这是可以用扩展欧几里德解的。 若gcd(a,b)|m那么方程就无解,直接输出-1。 (如果m%gcd(a,b)!=0无解) 否则我们可以解出上式的y1。回带得到一个特解x0=r1−y1a1。 通解可以写成x=x0+k∗lcm(a1,a2)也就是x≡x0(modlcm(a1,a2))。 这样我们就将两个方程合并为了一个。 重复进行以上操作,我们最终能将n个方程全部合并,再用扩展欧几德得解出来就好了。
 

 

#include
#include
#include
#include
using namespace std;typedef long long ll;ll a[100005],r[100005];int n;ll exgcd(ll a,ll b,ll &x,ll &y){ if(b == 0){ x = 1; y = 0; return a; } ll d = exgcd(b,a%b,x,y); ll tmp = x; x = y; y = tmp - a/b*y; return d;}ll solve(){ ll M = a[1],R = r[1],x,y; for(int i=2;i<=n;i++){ ll d = exgcd(M,a[i],x,y); if((R-r[i])%d!=0){
//无解 return -1; } x = (R-r[i])/d*x%a[i];//这才是真正的x,记得模a[i] R -= x*M;//特解x0,新的余数 M = M/d*a[i];//新的模数 R %= M; } return (R%M+M)%M;//确保R不为负数}int main(){ while(cin >> n){ for(int i=1;i<=n;i++){ cin >> a[i] >> r[i]; } ll ans = solve(); cout << ans << endl; } return 0;}

 

 

转载于:https://www.cnblogs.com/l609929321/p/7799476.html

你可能感兴趣的文章
C++/CLI
查看>>
Kerberos安全体系详解---Kerberos的简单实现
查看>>
Vuex demo
查看>>
新建swap分区的规划、挂载和自动挂载示例
查看>>
MySQL用户授权【转】
查看>>
我算是优秀的程序员吗?
查看>>
链表合并
查看>>
Delphi应用程序的调试(五)其他调试工具
查看>>
如何编写可维护的面向对象JavaScript代码
查看>>
win8: html5+css3+js
查看>>
Emacs 24.3支持cygwin上使用Win32 GUI
查看>>
对于一个排序数组,创建最低高度的Binary Tree
查看>>
Android-----判断是否有服务运行
查看>>
poj2392 Space Elevator(多重背包)
查看>>
oracle中恢复删除的表
查看>>
宏定义和内联函数
查看>>
设计一个栈,设计一个max()函数,求当前栈中的最大元素
查看>>
PHP 中的超全局变量
查看>>
WPF Converter 使用复杂参数的方法
查看>>
使用wireshark抓本机之间的包(转)
查看>>