• 表达整数的奇怪方式(EXCRT


    # 题意

    给定2n个整数,a1 , a2 , ...... , an 、m1 , m2 , ...... , mn,

    求一个最小的正整数x,满足∀ 1≤i≤n , x ≡  mi (mod ai)

    如果不存在解输出"-1",否则输出最小的正整数x

    数据范围:

    1 ≤ a≤ 231-1

    1 ≤ mi < ai

    1 ≤ n ≤ 25

    # 题解

    先考虑前两个式子:

    x ≡  m1 (mod a1) ↔ x = k1 * a1 + m1

    x ≡  m2 (mod a2) ↔ x = k2 * a2 + m2

    k1 * a1 + m1  k2 * a2 + m2

    k1 * a1 -k2 * a2 = m2-m1

    判断一下有没有解即 gcd(a1,a2) |(m2-m1) 是否成立

    扩展欧求出 k1 * a1 -k2 * a2 = gcd(a1,a2) 的解k1''k2''

    k1'=k1'' * (m2-m1)/gcd(a1,a2

    k2'=k2'' * (m2-m1)/gcd(a1,a2

    由x = k1 * a1 + m1或x = k2 * a2 + m2都可以得到x的通解

    其中k1通解=k+ k* (a2/gcd(a1,a2))显然k1取得最小值的时候x最小

    但是在和后面的式子合并的时候有了新的约束,

    x的最小值可能会改变所以先不具体求出x,

    用得到的k1或k2的通解构成一个新的同余等式

    k1通解=k1' + k* ( a2/gcd(a1,a2) )带入x = k1 * a1 + m1

    x = ( k1' + k* ( a2/gcd(a1,a2) ) ) * a1 + m1

    x = k * ( a* a2 )/gcd(a1,a2) + k1'*a1+m1

    a'=( a* a)/gcd(a1,a2) , m'=k1'*a1+m1

    x = k * a' + m'

    x = k3 * a3 + m3

    不断的合并到k-1,根据k的通解求得最小的x,

    k = k0 + t * (an/gcd(a',an)) 

    显然k0 % (an/gcd(a',an)) 即最小的解

     

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 ll n;
     5 ll exgcd(ll a,ll b,ll &x,ll &y){
     6     if(b==0){
     7         x=1;y=0;
     8         return a;
     9     }
    10     ll d=exgcd(b,a%b,y,x);
    11     y-=(a/b)*x;
    12     return d;
    13 }
    14 int main(){
    15     cin>>n;
    16     ll a1,m1;
    17     cin>>a1>>m1;
    18     for(int i=0;i<n-1;i++){
    19         ll a2,m2,k1,k2;
    20         cin>>a2>>m2;
    21         ll d=exgcd(a1,a2,k1,k2);//式子中的a2系数当作正数传入,得到的k可能为负数
    22         if((m2-m1)%d) {puts("-1");return 0;}
    23         k1*=(m2-m1)/d;//由裴蜀定理的解转化为方程解
    24         ll t=(a2/d);
    25         k1=(k1%t+t)%t;//对负数取模
    26         m1=k1*a1+m1;
    27         a1=a1/d*a2;
    28     }
    29     cout<<(m1%a1+a1)%a1<<endl;
    30     return 0;
    31 }

     

     

  • 相关阅读:
    poj(1458)(最长公共子序列)
    二叉搜索树
    hdu1087
    poj3641(学习了)
    平年和闰年的由来。。。。
    Linux system函数返回值(转)
    VS2010单元测试(转)
    QT QTableWidget 用法总结(转)
    QT显示图片(转)
    Qt正则表达式类QRegExp(转)
  • 原文地址:https://www.cnblogs.com/hhyx/p/12650252.html
Copyright © 2020-2023  润新知