• 中国剩余定理模板(互质与非互质)


    互质模板

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int Extended_Euclid(int a,int b,int &x,int &y)    //扩展欧几里得算法
     5 {
     6     int d;
     7     if(b==0)
     8     {
     9         x=1;y=0;
    10         return a;
    11     }
    12     d=Extended_Euclid(b,a%b,y,x);
    13     y-=a/b*x;
    14     return d;
    15 }
    16 
    17 int Chinese_Remainder(int a[],int w[],int len)    //中国剩余定理  a[]存放余数  w[]存放两两互质的数
    18 {
    19     int i,d,x,y,m,n,ret;
    20     ret=0;
    21     n=1;
    22     for (i=0;i<len;i++)
    23         n*=w[i];
    24     for (i=0;i<len;i++)
    25     {
    26         m=n/w[i];
    27         d=Extended_Euclid(w[i],m,x,y);
    28         ret=(ret+y*m*a[i])%n;
    29     }
    30     return (n+ret%n)%n;
    31 }
    32 
    33 
    34 int main()
    35 {
    36     int n,i;
    37     int w[15],b[15];
    38     while (scanf("%d",&n),n)   
    39     {
    40         for (i=0;i<n;i++)
    41         {
    42             scanf("%d%d",&w[i],&b[i]);
    43         }
    44         printf("%d/n",Chinese_Remainder(b,w,n));
    45     }
    46     return 0;
    47 }
    View Code

    非互质模板

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cmath>
     4 #include <iostream>
     5 #include <algorithm>
     6 using namespace std;
     7 #define LL long long
     8 const LL maxn=100000+10;
     9 LL a[maxn],b[maxn];
    10 //拓展欧几里得定理,求ax+by=gcd(a,b)的一组解(x,y),d=gcd(a,b)
    11 void gcd(LL a,LL b,LL &d,LL &x,LL &y)
    12 {
    13     if(!b){d=a;x=1;y=0;}
    14     else{gcd(b,a%b,d,y,x);y-=x*(a/b);}
    15 }
    16 LL china(LL n,LL a[],LL b[])
    17 {
    18     LL m1,r1,m2,r2,flag=0,i,d,x,y,c,t;
    19     m1=a[0],r1=b[0];
    20     flag=0;
    21     for(i=1;i<n;i++)
    22     {
    23         m2=a[i],r2=b[i];
    24         if(flag)continue;
    25         gcd(m1,m2,d,x,y);//d=gcd(m1,m2);x*m1+y*m2=d;
    26         c=r2-r1;
    27         if(c%d)//对于方程m1*x+m2*y=c,如果c不是d的倍数就无整数解
    28         {
    29             flag=1;
    30             continue;
    31         }
    32         t=m2/d;//对于方程m1x+m2y=c=r2-r1,若(x0,y0)是一组整数解,那么(x0+k*m2/d,y0-k*m1/d)也是一组整数解(k为任意整数)
    33         //其中x0=x*c/d,y0=x*c/d;
    34         x=(c/d*x%t+t)%t;//保证x0是正数,因为x+k*t是解,(x%t+t)%t也必定是正数解(必定存在某个k使得(x%t+t)%t=x+k*t)
    35         r1=m1*x+r1;//新求的r1就是前i组的解,Mi=m1*x+M(i-1)=r2-m2*y(m1为前i个m的最小公倍数);对m2取余时,余数为r2;
    36         //对以前的m取余时,Mi%m=m1*x%m+M(i-1)%m=M(i-1)%m=r
    37         m1=m1*m2/d;
    38     }
    39     if(flag)return -1;
    40     if(n==1&&r1==0)return m1;//结果不能为0
    41     return r1;
    42 }
    43 
    44 int main()
    45 {
    46     LL i,n,tt=0;
    47     
    48         cin>>n;
    49         for(i=0;i<n;i++)
    50             cin>>a[i]>>b[i];
    51         cout<<china(n,a,b)<<endl;
    52     
    53     return 0;
    54 }
    55 /*
    56  中国剩余定理(不互质形式)模板题。
    57  注意只有一组且剩余数为0的时候。结果不能为0
    58  */
    View Code
  • 相关阅读:
    PHPStorm下XDebug配置
    HDU 4633 Who's Aunt Zhang (Polya定理+快速幂)
    VC++深入详解-第五章学习心得
    nginx access log logrotate配置
    判断变量是否存在(python)
    一步一步学android之布局管理器——LinearLayout
    向前辈致敬 strspn
    poj 1087 (最大流)
    cocos2d-x Touch 事件应用的一个例子
    [置顶] C#扩展方法 扩你所需
  • 原文地址:https://www.cnblogs.com/zmin/p/8468777.html
Copyright © 2020-2023  润新知