zoukankan      html  css  js  c++  java
  • POJ 2891 Strange Way to Express Integers 中国剩余定理 数论 exgcd

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

    题意就是孙子算经里那个定理的基础描述不过换了数字和约束条件的个数……

    https://blog.csdn.net/HownoneHe/article/details/52186204

    这个博客提供了互质情况下的代码以及由此递推出的(另一个版本的)非互质情况下的代码。

    假如给出m[n],a[n]分别代表要求的除数和余数:

    互质情况下:

     ( 做n次 ) 对不包含m[i]的所有m求积 ( 互质的数的最小公倍数 ) , exgcd求出来逆元后*a[i], 然后对这n个结果求和取模. 

    设M为不包含m[i]的所有m的积, 

    那么 (M*x)%m[i]=1 --> (M*x)=1+m[i]*y --> (M*x)-m[i]*y=1

    exgcd后的M*x就是单位1 ( 逆元 ) 了. 

    非互质情况下:

    M被分解质因子,重复质因子的指数都变为1(最小公倍数),然后做同样操作。

     

    我这里写的是一个相对优化的代码(博客中的第二个版本),使用的空间更小,求最小公倍数更加方便,也更不容易过程中溢出,嗯读一下代码应该就明白了。

    我总觉得我以前写过中国剩余定理啊为什么现在这么详细解释……

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #define LL long long
     7 const LL maxn=300010;
     8 LL n;
     9 void exgcd(LL a,LL b,LL &d,LL &x,LL &y){
    10     if(!b){
    11         x=1;y=0;d=a;
    12         return;
    13     }exgcd(b,a%b,d,x,y);
    14     LL z=x;x=y;
    15     y=z-(LL)(a/b)*y;
    16 }
    17 int main(){
    18     while(~scanf("%lld",&n)){
    19         LL mc=0,ac=0,m1=0,a1=0,f=0;
    20         for(int i=1;i<=n;i++){
    21             scanf("%lld%lld",&m1,&a1);
    22             if(f)continue;
    23             if(i==1){mc=m1;ac=a1;continue;}
    24             LL x,y,d,c=a1-ac; exgcd(mc,m1,d,x,y);
    25             if(c%d){f=1;continue;}
    26             x=(((x*(c/d))%m1)+m1)%m1;
    27             ac+=mc*x;
    28             mc=mc/d*m1;
    29             ac=ac%mc;
    30         }
    31         if(f)printf("-1
    ");
    32         else printf("%lld
    ",ac);
    33     }
    34 }
    View Code

  • 相关阅读:
    TCP的三次握手与四次挥手
    关系型数据库和非关系型数据库的区别
    wedpack打包的基本使用
    express的中间件与next()
    react-redux (react)
    判断数据类型的几种方式
    关于NODE__APP在windows系统解决适配问题
    中间件,前后端分离思想
    移动端
    EasyUI combobox 动态下拉列表
  • 原文地址:https://www.cnblogs.com/137shoebills/p/8707480.html
Copyright © 2011-2022 走看看