您的位置:首页 > 其它

HDU_1573 X问题 中国剩余定理

2012-05-21 20:05 295 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1573

题意:

给定一组同余方程组,和一个N,求方程组小于等于N的的解的个数。

思路:

中国剩余定理的运用,但是需要主要的是这里的mi不是两两互质的,因此不能直接用中国

剩余定理,需要两个两个式子地进行求解,假设用两个式子:

x = a1( mod m1 ) 和 x = a2 ( mod m2) --> x = b1*m1 + a1 和 x = b2 * m2 + a2 ;

---> b1 * m1 + a1 = b2 * m2 + a2 ; ---> m1 * b1 - m2 * b2 = a2 - a1 这样我们只需要求出上

式中的非负的b1就可以得出原来的x,此时相当于两个式子合成了一个式子:x' = x( mod

lcm(m1 , m2 ) )。

代码:

#include<stdio.h>
#include<string.h>
typedef long long LL ;
LL  nCas ;
LL N , M ;
LL a[20] , m[20] ;

LL ex_gcd(LL a, LL b , LL& x ,LL& y){
if(b == 0){
x = 1 ; y = 0 ;
return a ;
}
else{
LL d = ex_gcd(b , a%b ,x, y) ;
LL t = x ;
x = y ;
y = t - a/b*y ;
return d ;
}
}
void solve(){
LL x, y ;
LL a1, a2 , m1 , m2  ;
a1 = a[1] ; m1 = m[1];
for(int i=2;i<=M;i++){
a2 = a[i] ; m2 = m[i] ;
LL d = ex_gcd(m1, m2 , x, y) ;
if( (a2 - a1)%d != 0){
printf("0\n"); return ;
}
LL res  = x * ( (a2 - a1)/d ) ;
res = (res % m2 + m2) % m2 ;        //确保结果非负
a1 = a1 + m1 * res ;
m1 = m1/d*m2 ;
a1 = ( a1 % m1 + m1 ) % m1 ;        //确保结果非负
}
LL ans = (N - a1) / m1 + 1 ;
if( a1 > N )    ans = 0 ;
if( a1 == 0 )   ans-- ;
printf("%I64d\n",ans) ;
}

int main(){
scanf("%I64d",&nCas);
for(int cas=1;cas<=nCas;cas++){
scanf("%I64d %I64d",&N,&M);
for(int i=1;i<=M;i++)  scanf("%I64d",&m[i]);
for(int i=1;i<=M;i++)  scanf("%I64d",&a[i]);
solve() ;
}
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: