HDU_1573 X问题 中国剩余定理

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 ;
}

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值