HDU X问题 中国剩余定理--求满足条件的个数

X问题

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2522    Accepted Submission(s): 790


Problem Description
求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … (0 < a[i] <= 10)。
 

 

Input
输入数据的第一行为一个正整数T,表示有T组测试数据。每组测试数据的第一行为两个正整数N,M (0 < N <= 1000,000,000 , 0 < M <= 10),表示X小于等于N,数组a和b中各有M个元素。接下来两行,每行各有M个正整数,分别为a和b中的元素。
 

 

Output
对应每一组输入,在独立一行中输出一个正整数,表示满足条件的X的个数。
 

 

Sample Input
3
10 3
1 2 3
0 1 2
100 7
3 4 5 6 7 8 9
1 2 3 4 5 6 7
10000 10
1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 5 6 7 8 9
 
Sample Output
1
0
3
 
Author
lwg
 

 

Source
 

 

Recommend
linle
 
小小的变形。求个数。要考虑不存在到情况,也要考虑数据0,0存在的情况。
x=a(mod n),显然对于所有到n到最小公倍数,x*最小公倍数=a(mod n);
统计个数就好了。
 
这道题也可以变形一下,求区间[l,r]满足到个数!!!!!
  1 #include<iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<cstdlib>

  5 using namespace std;

  6 

  7 

  8 __int64 m[13];

  9 __int64 A[13];

 10 

 11 __int64 Ex_gcd(__int64 a,__int64 b,__int64 &x,__int64 &y)

 12 {

 13     if(b==0)

 14     {

 15         x=1;

 16         y=0;

 17         return a;

 18     }

 19     __int64 g=Ex_gcd(b,a%b,x,y);

 20     __int64 hxl=x-(a/b)*y;

 21     x=y;

 22     y=hxl;

 23     return g;

 24 }

 25 

 26 __int64 gcd(__int64 a,__int64 b)

 27 {

 28     if(b==0)

 29     return a;

 30     else return gcd(b,a%b);

 31 }

 32 

 33 void make_ini(__int64 n,__int64 M)

 34 {

 35     __int64 i,x,y,m1,r1,m2,r2,t,d,c,num=0;

 36     bool flag;

 37     m1=m[1];r1=A[1];

 38     flag=false;

 39     for(i=2;i<=n;i++)

 40     {

 41         r2=A[i];

 42         m2=m[i];

 43         if(flag==true) continue;

 44         d=Ex_gcd(m1,m2,x,y);

 45         c=r2-r1;

 46         if(c%d)

 47         {

 48             flag=true;

 49             continue;

 50         }

 51 

 52         x=c/d*x;

 53         t=m2/d;

 54         x=(x%t +t)%t;

 55         r1=m1*x+r1;

 56         m1=m1*m2/d;

 57     }

 58     if(flag==true)

 59     {

 60         printf("0\n");

 61         return;

 62     }

 63     if(r1==0 && n>1)

 64     {

 65         m1=m[1];r1=m[1];

 66         for(i=2;i<=n;i++)

 67         m1=m1*m[i];

 68         for(i=2;i<=n;i++)

 69         r1=gcd(r1,m[i]);

 70         r1=m1/r1;//一个解

 71         m1=r1;//最小公倍数

 72     }

 73     if(r1==0 && n==1)

 74     {

 75         r1=m[1];

 76         m1=m[1];

 77     }

 78     if(r1>M)

 79     num=0;

 80     else

 81     {

 82         M=M-r1;

 83         num=M/m1+1;

 84     }

 85     printf("%I64d\n",num);

 86 }

 87 

 88 int main()

 89 {

 90     __int64 T,N,M,i;

 91     while(scanf("%I64d",&T)>0)

 92     {

 93         while(T--)

 94         {

 95             scanf("%I64d%I64d",&M,&N);

 96             for(i=1;i<=N;i++)

 97             scanf("%I64d",&m[i]);

 98 

 99             for(i=1;i<=N;i++)

100             scanf("%I64d",&A[i]);

101             make_ini(N,M);

102         }

103     }

104     return 0;

105 }

 

你可能感兴趣的:(HDU)