数论 线性同余方程的应用 poj2891

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

2
8 7
11 9

Sample Output

31

解同于方程组:

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

 

题解

若模数两两互质,我们可以用中国剩余定理来解。 
这里我们先考虑两个方程:

    xr1(moda1)
    xr2(moda2)
我们可以写成:
     x+y1a1=r1
     xy2a2=r2

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

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数论基础及其应用 作者:沈忠华 编著 出版时间:2015年版 内容简介   《数论基础及其应用》为数学与密码学交叉学科的特色教材,内容包括整除理论、同余、连分数、同余方程、原根。《数论基础及其应用》以数论知识为主线,有机地融入数论应用(主要是在密码学中的应用)的内容,理论与应用的知识的广度和深度都适度。《数论基础及其应用》可作为数学与应用数学专业、信息与计算科学专业和信息安全专业的本科生基础教材,也可作为密码学与信息安全专业的研究生教材。 目录 前言 第1章整除理论 1.1带余数除法 1.2辗转相除法 1.3最大公约数的性质 1.4最小公倍数 1.5算术基本定理 第2章同余 2.1同余的基本性质 2.2计算星期几 2.3循环比赛 第3章简单密码 3.1仿射加密 3.2矩阵加密 第4章剩余系 4.1完全剩余系 4.2简化剩余系 4.3Euler定理,Fermat定理 4.4数论函数 第5章不定方程 5.1一次不定方程 5.2方程x2+y2=x2 第6章同余方程 6.1同余方程的基本概念 6.2孙子定理 6.3模ρα的同余方程 6.4素数模的同余方程 第7章公钥密码 7.1公钥密码系统 7.2RSA加密 第8章二次剩余 8.1素数模的二次同余方程 8.2Legendre符号,二次互反律 8.3Jacobi符号 第9章原根 9.1指数及其基本性质 9.2原根与指标 9.3伪素数 第10章实数的表示 10.1连分数的基本性质 10.2实数的连分数表示 10.3循环连分数 10.4实数的b进制表示 第11章平方和 11.1二平方之和 11.2四平方之和 附录

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值