• poj 2891 扩展欧几里得解一元线性同余方程组


    http://poj.org/problem?id=2891

    题意:

    选择K个不同的正整数a1,a2.....ak,对于某个整数m分别对ai求余对应整数ri,如果当选择a1,a2,....ak,那么m可由整数对组合(ai,ri)唯一确定。

    现在已知a1,a2,...ak以及所有的整数对(ai,ri)求最小的非负整数m的值。

    设 a,b为整数,且a(!Ξ)0(mod)m,则称同余方程 ax Ξ b(mod)m为一次同余方程

    一次同余方程的求解步骤

    1:求gcd(a,m)

    2:令d = gcd(a,m) 如果d不能整除b则无解,否则转3

    3:根据ex_gcd 求得一个解x0;

    用扩展欧几里得求解的具体做法如下:

    (1):用ex_gcd求得满足 ax' + my' = d 的x'和y'。具体方法是将 ax'+my' = d 变形可以得到 ax' = d - my';

    对变形后的式子两边同时取模m得 ax'Ξd(mod)m,至此可见x'是同余方程的解

    (2):根据x'求x0。具体方法是:由于d能整除b 设 p = b/d,则根据同余式的性质得到:a(px')≡dp(mod)m即:a(px')≡b(mod)m.因此x0 = px' = b/d*x'(mod)m.

    4:根据求得的x0可以得到其他d-1个解为 xi = (x0 + i*m/d)(mod)m, i = 1,2,...d-1.

    然后根据上面的方法去解上面的题。代码是求得方程组小于m的非负整数解。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <stack>
     5 #include <queue>
     6 #include <map>
     7 #include <algorithm>
     8 #include <vector>
     9 
    10 using namespace std;
    11 
    12 const int maxn = 1000005;
    13 
    14 typedef long long LL;
    15 
    16 LL ex_gcd(LL a,LL b,LL &x,LL &y)
    17 {
    18    if(b == 0){
    19         x = 1;
    20         y = 0;
    21         return a;
    22    }
    23    LL r = ex_gcd(b,a%b,x,y);
    24    LL t = x;
    25       x = y;
    26       y = t - a/b*y;
    27       return r;
    28 }
    29 int main()
    30 {
    31     LL i,n,a1,r1,a2,r2,ans,a,b,c,d,x0,y0;
    32     while(scanf("%lld",&n)!=EOF){
    33         bool flag = 1;
    34         scanf("%lld%lld",&a1,&r1);
    35         for( i=1;i<n;i++){
    36             scanf("%lld%lld",&a2,&r2);
    37             a = a1;
    38             b = a2;
    39             c = r2-r1;
    40             LL d = ex_gcd(a,b,x0,y0);
    41             if(c%d!=0){
    42                 flag = 0;
    43             }
    44             int t = b/d;
    45             x0 = (x0*(c/d)%t+t)%t;//保证x0为正
    46             r1 = a1*x0 + r1;
    47             a1 = a1*(a2/d);
    48 
    49 
    50         }
    51         if(!flag){
    52             puts("-1");
    53             continue;
    54         }
    55         printf("%lld
    ",r1);
    56     }
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    八十九:ECMAScript6扩展之字符串、for-of
    八十八:ECMAScript6之解构赋值
    八十七:ECMAScript6基础入门之let、const
    八十六:JavaScript之表单验证案例
    八十五:JavaScript之正则表达式之实现正则测试工具
    八十四:JavaScript之正则表达式之常用的正则表达式
    vim常用命令总结(转)
    Linux常用命令
    LinkedBlockingQueue的put,add跟offer的区别
    RabbitMQ消息确认(发送确认,接收确认)
  • 原文地址:https://www.cnblogs.com/lmlyzxiao/p/4931129.html
Copyright © 2020-2023  润新知