hdu 1573 X问题

分析:中国剩余定理的求解,其中a[i]与a[j]不一定互质。

   对于非互质版的中国剩余定理可以通过迭代的办法来求。

   对于最终的通解  ans=At+B,我们可以通过逐一合并两个方程来更新A B,最后来得到答案。

   最初A=a[1],B=b[1];然后将A B 带入下一个方程得到(At+B)mod a[i]==b[i]..得到一个特解tt,然后在求出此方程通解,再带回到ans中更新A B...

   依次类推。。。。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define N 15
 6 using namespace std;
 7 typedef long long ll;
 8 ll a[N],b[N];
 9 int t,m;
10 ll n,A,B;
11 ll gcd(ll a,ll b){
12     return b?gcd(b,a%b):a;
13 }
14 ll exgcd(ll a,ll b,ll &x,ll &y){
15     if(b==0){
16         x=1;y=0;
17         return a;
18     }
19     ll d=exgcd(b,a%b,x,y);
20     ll t=x;
21     x=y;
22     y=t-(a/b)*y;
23     return d;
24 }
25 void solve(){
26     A=a[1],B=b[1];
27     bool flag=1;
28     for(int i=2;i<=m;i++){
29         ll x,y;
30         ll ans=exgcd(A,a[i],x,y);
31         if((b[i]-B)%ans){
32             flag=0;break;
33         }
34         x=x*(b[i]-B)/ans;
35         x=(x%(a[i]/ans)+(a[i]/ans))%(a[i]/ans);
36         B=A*x+B;
37         A=A*a[i]/ans;
38         B=(B%A+A)%A;
39     }
40     if(flag==0||n<B)cout<<0<<endl;
41     else
42         cout<<(n-B)/A+1-(B==0?1:0)<<endl;
43 }
44 int main(){
45     cin>>t;
46     while(t--){
47         cin>>n>>m;
48         for(int i=1;i<=m;i++)cin>>a[i];
49         for(int i=1;i<=m;i++)cin>>b[i];
50         solve();
51     }
52     return 0;
53 }
posted @ 2012-10-24 17:10  silver__bullet  阅读(390)  评论(0编辑  收藏  举报