zoukankan      html  css  js  c++  java
  • CQOJ 扩展中国剩余定理 【数论】

    原题: 

       求在小于等于 n 的正整数中有多少个X满足:

      X = b[1] (mod a[1]) 

      X = b[2] (mod a[2]) 

      .....

    题解:

      对于中国剩余定理的理解:

        对于前两式

          X=B[1] (mod A[1])  =>  A[1]*a+B[1]=X

          X=B[2] (mod A[2])  =>  A[2]*b+B[2]=X

        两式相减可化为     A[1]*a-A[2]*b=B[2]-B[1]

        根据扩展欧几里得(一般式Ax+By=C) 可解得 a , b

        又满足二式的X' 有 X'=a*A[1]+B[1]   (带入第二式亦可)  且 X'为正整数

         则特别的

         X‘=x + Lca  (x为X'最小取值)

        因此二式可合并为 Lca*c+x=X

       显而易见,接下来的方程皆可合并直到由最末方程推出最终解

     1 /*
     2     中国剩余定理 
     3 */
     4 #include<queue>
     5 #include<cstdio>
     6 #include<cstring>
     7 #include<iostream>
     8 #include<algorithm>
     9 using namespace std;
    10 typedef long long lol;
    11 int T;
    12 int N,M;
    13 lol A[15];
    14 lol B[15];
    15 void Read(lol &x){
    16     x=0;
    17     char c=getchar();
    18     while(!isdigit(c)) c=getchar();
    19     while(isdigit(c)) x=x*10-'0'+c,c=getchar();
    20     return ;
    21 }
    22 lol ExGcd(lol a,lol b,lol &x,lol &y){
    23     if(b==0){
    24         x=1;
    25         y=0;
    26         return a;
    27     }
    28     lol xx,yy;
    29     lol res=ExGcd(b,a%b,xx,yy);
    30     x=yy;
    31     y=xx-a/b*yy;
    32     return res;
    33 }
    34 lol Calc(lol a,lol b,lol c,lol &g){
    35     int ok=0;
    36     lol x,y;
    37     if(a<b) swap(a,b),ok=1;
    38     lol res=ExGcd(a,b,x,y);
    39     g=abs(res);
    40     if(ok) swap(a,b),swap(x,y);
    41     x=c/res*x;
    42     lol t=abs(b/res);
    43     return ((x%t)+t)%t;
    44 }
    45 void Solve(){
    46     for(int i=1;i<M;i++){
    47         lol g,lc;
    48         lol res=Calc(A[i],-A[i+1],B[i+1]-B[i],g);
    49         lc=A[i]*A[i+1]/g;
    50         A[i+1]=lc;
    51         B[i+1]=(res*A[i]+B[i])%lc;
    52     }
    53     lol ans=(N-B[M])/A[M];
    54     if(B[M]!=0 && B[M]<=N) ans++;
    55     cout<<ans<<endl;
    56     return ;
    57 }
    58 void Next_Main(){
    59     scanf("%d%d",&N,&M);
    60     for(int i=1;i<=M;i++)
    61      Read(A[i]);
    62     for(int i=1;i<=M;i++)
    63      Read(B[i]);
    64     Solve();
    65     return ;
    66 }
    67 int main(){
    68     scanf("%d",&T);
    69     while(T--) Next_Main();
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    fastjson 解析 字符串 为对象
    fastjson 对类模板进行 parseObject
    VUE路由跳转传递参数的几种方式
    ES 常用设置修改
    springboot图片路径形式获取图片
    Elasticsearch根据ID进行查询
    linux 常用命令
    Elasticsearch常用操作
    java8 stream接口终端操作 count,anyMatch,allMatch,noneMatch
    logstash数据迁移
  • 原文地址:https://www.cnblogs.com/Aloyd/p/9296607.html
Copyright © 2011-2022 走看看