zoukankan      html  css  js  c++  java
  • hdu 1573 X问题

      数论题,本想用中国剩余定理,可是取模的数之间不一定互质,用不了,看到网上有篇文章写得很好的:数论——中国剩余定理(互质与非互质),主要是采用合并方程的思想:

      大致理解并参考他的代码后便去试试hdu上这道题,可还是wa了数遍。

     1 #include<cstdio>
     2 #define  scd(x)  scanf("%d",&x)
     3 #define  sclld(x)  scanf("%I64d",&x)
     4 #define  prd(x)  printf("%d
    ",x)
     5 #define  For(i,s,t)  for(int i=s; i<t; ++i)
     6 typedef long long LL;
     7 
     8 LL gcd(LL a, LL b)    {    return b==0? a: gcd(b,a%b);     }
     9 LL lcm(LL x, LL y)    {    return x/gcd(x,y)*y;    }
    10 
    11 void gcd(LL a, LL b, LL &d, LL &x, LL &y){
    12     if(!b)    {    d=a;  x=1;  y=0;    }
    13     else   {    gcd(b,a%b,d,y,x);    y-= x*(a/b);    }
    14 }
    15 
    16 LL inv(LL a, LL n){
    17     LL d,x,y;
    18     gcd(a,n,d,x,y);
    19     return d==1? (x+n)%n:-1;
    20 }
    21 
    22 bool merge(LL a1, LL n1, LL a2, LL n2, LL &aa, LL &nn){
    23     LL d= gcd(n1,n2), c= a2-a1;
    24     if(c%d)      return 0;
    25     c= (c%n2+n2)%n2;
    26     c/= d;
    27     n2/= d;
    28     c= c*inv(n1/d,n2)%n2;
    29     c= c*n1+a1;
    30     nn= n1*n2;
    31     aa= (c%nn+nn)%nn;
    32     return true;
    33 }
    34 
    35 LL ext_china(LL len, LL a[], LL n[]){
    36     LL a1= a[0], n1= n[0];
    37     for(LL i=1; i<len; ++i){
    38         LL aa, nn;
    39         if(!merge(a1,n1,a[i],n[i],aa,nn))    return -1;
    40         a1= aa;
    41         n1= nn;
    42     }
    43     return (a1%n1+n1)%n1;
    44 }
    45 
    46 LL a[12], b[12];
    47 
    48 int main(){
    49     int t;
    50     LL n,m,M;
    51     scd(t);
    52     while(t--){
    53         sclld(n);    sclld(m);
    54         M= 1;
    55         For(i,0,m){
    56             sclld(a[i]);
    57             M= lcm(M,a[i]);
    58         }
    59         For(i,0,m)    sclld(b[i]);
    60         LL tmp= ext_china(m,b,a);
    61         if(tmp== -1){
    62             puts("0");
    63             continue;
    64         }
    65         int ans= 0;
    66         while(tmp<=n){
    67             if(tmp)      ++ans;
    68             tmp+= M;
    69         }
    70         prd(ans);
    71     }
    72     return 0;
    73 }
    View Code

      不想用cin,cout便用宏替换来代替输入输出了,有几个wa点:1.ext_china中有可能返回-1,要分开处理;2. tmp值一开始可能是0,不能算入最后结果中;3. M的值不能是a数组的简单相乘,应是它们的最小公倍数才对。

  • 相关阅读:
    读Android之大话设计模式--前言和说明
    把二叉树打印成多行
    按之字形顺序打印二叉树
    对称的二叉树
    二叉树的下一个结点
    链表中环的入口结点
    字符流中第一个不重复的字符
    表示数值的字符串
    构建乘积数组
    数组中重复的数字
  • 原文地址:https://www.cnblogs.com/Newdawn/p/4364903.html
Copyright © 2011-2022 走看看