zoukankan      html  css  js  c++  java
  • poj 2891 Strange Way to Express Integers(中国剩余定理)

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


    题意:求解一个数x使得 x%8 = 7,x%11 = 9;
       若x存在,输出最小整数解。否则输出-1;
    
    
    
    ps:
    思路:这不是简单的中国剩余定理问题,由于输入的ai不一定两两互质,而中国剩余定理的条件是除数两两互质。
       这是一般的模线性方程组,对于
        X mod m1=r1
        X mod m2=r2
        ...
        ...
        ...
        X mod mn=rn
    首先,我们看两个式子的情况
    X mod m1=r1……………………………………………………………(1)
    X mod m2=r2……………………………………………………………(2)
    则有 
    X=m1*k1+r1………………………………………………………………(*)
    X=m2*k2+r2
    那么 m1*k1+r1=m2*k2+r2
    整理,得
    m1*k1-m2*k2=r2-r1
    令(a,b,x,y,m)=(m1,m2,k1,k2,r2-r1)。原式变成
    ax+by=m
    熟悉吧?
    
    此时,由于GCD(a,b)=1不一定成立,GCD(a,b) | m 也就不一定成立。所以应该先判 若 GCD(a,b) | m 不成立,则!!

    。方程无解!

    !!

    否则,继续往下。 解出(x,y),将k1=x反代回(*)。得到X。 于是X就是这两个方程的一个特解,通解就是 X'=X+k*LCM(m1,m2) 这个式子再一变形,得 X' mod LCM(m1,m2)=X 这个方程一出来。说明我们实现了(1)(2)两个方程的合并。

    令 M=LCM(m1,m2)。R=r2-r1 就可将合并后的方程记为 X mod M = R。 然后,扩展到n个方程。 用合并后的方程再来和其它的方程按这种方式进行合并,最后就能仅仅剩下一个方程 X mod M=R,当中 M=LCM(m1,m2,...,mn)。 那么,X便是原模线性方程组的一个特解,通解为 X'=X+k*M。 假设,要得到X的最小正整数解,就还是原来那个方法: X%=M; if (X<0) X+=M;


    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <vector>
    #include <math.h>
    #include <string.h>
    #include <queue>
    #include <string>
    #include <stdlib.h>
    #define LL long long
    #define _LL __int64
    #define eps 1e-8
    
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int maxn = 10;
    
    _LL k;
    _LL M;
    
    _LL extend_gcd(_LL a,_LL b,_LL &x,_LL &y)
    {
        if(b == 0)
        {
            x = 1;
            y = 0;
            return a;
        }
        else
        {
            _LL r = extend_gcd(b,a%b,x,y);
            _LL t = x;
            x = y;
            y = t-a/b*y;
            return r;
        }
    }
    
    int main()
    {
        _LL a1,m1,a2,m2,x,y,i,d;
        while(scanf("%lld",&k)!= EOF)
        {
            bool flag = true;
            scanf("%lld %lld",&m1,&a1);
            for(i = 1; i < k; i++)
            {
                scanf("%lld %lld",&m2,&a2);
    
                d = extend_gcd(m1,m2,x,y);
    
                if((a2-a1)%d != 0)
                    flag = false;
    
                _LL t = m2/d;
                x *= (a2-a1)/d;
                x = (x%t + t)%t;
                //注意新的m1,a1是怎么得来的
                a1 = x*m1+a1;
                m1 = m1*m2/d;
                a1 = (a1%m1+m1)%m1;
            }
            if(flag == true)
                printf("%lld
    ",a1);
            else printf("-1
    ");
    
        }
        return 0;
    }
    


  • 相关阅读:
    null和undefined的区别
    百度小程序组件引用问题
    hbase优化操作与建议
    Hbase Rowkey设计原则
    kafka容器报内存不足异常(failed; error='Cannot allocate memory' (errno=12))
    Hbase安装
    四、hive安装
    一、linux安装mysql
    三、hadoop、yarn安装配置
    linux下磁盘进行分区、文件系统创建、挂载和卸载
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5160286.html
Copyright © 2011-2022 走看看