zoukankan      html  css  js  c++  java
  • 【poj 2891】Strange Way to Express Integers(数论--拓展欧几里德 求解同余方程组 模版题)

    题意:Elina看一本刘汝佳的书(O_O*),里面介绍了一种奇怪的方法表示一个非负整数 m 。也就是有 k 对 ( ai , ri ) 可以这样表示——m%ai=ri。问 m 的最小值。

    解法:拓展欧几里德求解同余方程组的最小非负整数解。(感觉挺不容易的......+_+@)

            先看前2个关系式:                       m%a1=r1 和 m%a2=r2 
                                                                m-a1*x=r1 和 m-a2*y=r2 →
                                                                m=a1*x+r1 和 m=a2*y+r2
                                                                a1*x-a2*y=r2-r1
           于是用拓展欧几里德求得一个满足这2个关系式/方程联立的最小非负整数解 (x',y')。
      那么存在一个:                                  m'-a1*x'=r1 和 m'-a2*y'=r2 
                                                                m'=a1*x'+r1=a2*y'+r2
                                                                m' %a1=m%a1 和 m' %a2=m%a2 
                                                                m' %lcm(a1,a2)=m%lcm(a1,a2)
                                                                m=m'+k*lcm(a1,a2)
                                                                m=(a1*x'+r1)+lcm(a1,a2)*k
                                                                m=      r'       +         a'    *x
                                                               
    ......
                                                               
    m=ak*y'+rk+lcm(ak-1,ak)*k
                                                      而又   m=ak*y'+rk , r'=ak*y'+rk
                                                      所以   m=r'
           接着继续将这个式子与  m=a3*y+r3 联立,同样地得到一个新的方程,再一直继续联立下去,由于 x 保证了尽量下,最后的 r' 就是尽量小的答案。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 using namespace std;
     6 typedef long long LL;
     7 
     8 LL mabs(LL x) {return x>0?x:-x;}
     9 LL exgcd(LL a,LL b,LL& x,LL& y)
    10 {
    11     if (!b) {x=1,y=0; return a;}
    12     LL d,tx,ty;
    13     d=exgcd(b,a%b,tx,ty);
    14     x=ty,y=tx-(a/b)*ty;
    15     return d;
    16 }
    17 int main()
    18 {
    19     LL k;
    20     while (scanf("%I64d",&k)!=EOF)
    21     {
    22       LL aa,rr,a,r; bool ok=false;
    23       for (LL i=1;i<=k;i++)
    24       {
    25         scanf("%I64d%I64d",&aa,&rr);
    26         if (ok) continue;
    27         if (i==1) a=aa,r=rr;
    28         else
    29         {//求解同余方程
    30           LL d,x,y,t;
    31           d=exgcd(a,aa,x,y);//ax-aay=rr-r 有无正负号没有关系
    32           if ((rr-r)%d!=0) {ok=true;continue;}//break;} 多组数据要读入完!
    33           x=x*((rr-r)/d);//1个解
    34           t=mabs(aa/d);//mabs
    35           x=(x%t+t)%t;//最小非负整数解
    36           
    37           r=a*x+r,a=a*aa/d;//a=lcm(a,aa)=a*aa/gcd(a,aa)=a*aa/d;
    38         }
    39       }
    40       if (!ok) printf("%I64d
    ",r);
    41       else printf("-1
    ");
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    HDU1029 Ignatius and the Princess IV
    UVA11039 Building designing【排序】
    UVA11039 Building designing【排序】
    POJ3278 HDU2717 Catch That Cow
    POJ3278 HDU2717 Catch That Cow
    POJ1338 Ugly Numbers(解法二)
    POJ1338 Ugly Numbers(解法二)
    UVA532 Dungeon Master
    UVA532 Dungeon Master
    POJ1915 Knight Moves
  • 原文地址:https://www.cnblogs.com/konjak/p/6063351.html
Copyright © 2011-2022 走看看