中国剩余定理及扩展模板

m互质的情况:中国剩余定理
洛谷 P3868 [TJOI2009]猜数字
数据比较卡,所以要优化一点.

#include<cstdio>
typedef long long ll;
const ll mod=1e18+7;
ll qmul(ll a,ll b,ll mod){
   
    ll ans=0;
    while(b>0){
   
        if(b&1) ans=(ans+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return ans;
}
void exgcd(ll a,ll b,ll &x,ll &y){
   
	if(b==0){
   
		x=1,y=0;
		return ;
	}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
}
int main(){
   
	ll a[100],b[100];
	ll k;
	scanf("%lld",&k);
	ll res=0,M=1;
	for(int i=0;i<k;i++)
		scanf("%lld",&a[i]);
	for(int i=0;i<k;i++){
   
		scanf("%lld",&b[i]);
		M*=b[i];
	}
	for(int i=0;i<k;i++) a[i]=(a[i]%b[i]+b[i])%b[i];
	for(int i=0;i<k;i++){
   
		ll mm=M/b[i],x,y;
		exgcd(mm,b[i],x,y);
		x=(x%b[i]+b[i])%b[i];
		res=(res+qmul(qmul(mm,x,M),a[i],M))%M;
	}
	printf("%lld\n",(res%M+M)%M);
	return 0;
}

m不互质的情况:扩展中国剩余定理
洛谷P4777

#include<cstdio>
typedef long long ll;
const int maxn=1e5+10;
ll qmul(ll a,ll b,ll mod){
   
    ll ans=0;
    while(b>0){
   
        if(b&1) ans=(ans+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return ans;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
   
    if(b==0){
   x=1;y=0;return a;}
    ll gcd=exgcd(b,a%b,x,y);
    ll tp=x;
    x=y; y=tp-a/b*y;
    return gcd;
}
int main(){
   
	ll a[maxn],b[maxn];
	ll n;
	scanf("%lld",&n);
	for(int i=0;i<n;i++)
		scanf("%lld%lld",&b[i],&a[i]);
	ll M=b[0],ans=a[0];//第一组特判
	for(int i=1;i<n;i++){
   
		ll x,y,c=(a[i]-ans%b[i]+b[i])%b[i];
		ll gcd=exgcd(M,b[i],x,y);
		if(c%gcd!=0)	return -1;//无解情况
		x=qmul(x,c/gcd,b[i]/gcd);
		ans+=x*M;
		M*=b[i]/gcd; 
		ans=(ans%M+M)%M;
	}
	
	printf("%lld",ans); 
	return 0;
}
全部评论

相关推荐

wuwuwuoow:Redisson 写错了,记得 Redis 儿子以后都不会写错。其他没啥问题,海投就行。
点赞 评论 收藏
分享
头像
03-30 21:02
已编辑
武汉大学 Java
ALEX_BLX:虽然说聊天记录不可信,不过这个趋势确实如此但我觉得也要想到一点就是卷后端的人里真正有“料”的人又有多少,我说的这个料都不是说一定要到大佬那种级别,而是就一个正常的水平。即使是现在也有很多人是跟风转码的,2-3个月速成后端技术栈的人数不胜数,但今时不同往日没可能靠速成进大厂了。这种情况就跟考研一样,你能上考场就已经打败一半的人了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务