EXCRT没过样例,悬赏1关注
查看原帖
EXCRT没过样例,悬赏1关注
502758
ForMyDream楼主2023/1/14 20:37

做法:龟速乘,样例没过求调,谢谢!

#include<iostream>
#define LL long long 
using namespace std;
#define maxn 100001

LL m[maxn],a[maxn],n;

LL exgcd(LL a,LL b,LL &x,LL &y){
	if (b==0){
		x=1,y=0;
		return a;
	}
	LL d=exgcd(b,a%b,x,y);
	LL t=x;
	x=y;
	y=x-a/b*y;
	return d;
}

LL slowmul(LL a,LL b,LL mod){
	// a * b 防止越界
	LL ans=0;
	while (b){
		if (b&1){
			ans=(ans+a)%mod;
		}
		a=(a+a)%mod;
		b>>=1;
	} 
	return ans;
}

LL excrt(){
	LL m1,m2,r1,r2,P,a1,a2;
	m1=m[1],a1=a[1];
	for (int i=2;i<=n;i++){
		// 再合并 n-1 次
		m2=m[i],a2=a[i];
		LL gcd=exgcd(m1,m2,r1,r2);
		if ((a1-a2)%gcd) return -1;
		r1=slowmul(r1,(a1-a2)/gcd,m1*m2/gcd); // 特解(exgcd中的)
		r1=(r1%(m2/gcd)+m2/gcd)%(m2/gcd);
		a1=a1+m1*r1;
		m1=m1*m2/gcd; 
	}
	return (a1%m1+m1)%m1;
}

int main(){
	scanf("%lld",&n);
	for (int i=1;i<=n;i++){
		scanf("%lld%lld",&m[i],&a[i]);
	}
	printf("%lld\n",excrt());
	return 0;
}
2023/1/14 20:37
加载中...