EXCRT模板最后两个点WA,疑似溢出,求高人指点
查看原帖
EXCRT模板最后两个点WA,疑似溢出,求高人指点
564732
TimSwn090306楼主2023/4/29 11:30

初二锰锌一个中午硬啃了一个小时的扩展欧几里得,中国剩余定理,和扩展中国剩余定理……逻辑上应该问题不大,个人猜测是溢出或者取模的问题但是找不出来 bug 在哪里,求高人指点

78pts 提交记录

#include <bits/stdc++.h>
#define ll long long
#define Mod(x,m) ((x)%(m)+(m))%(m)
using namespace std;
const int maxn=1e5+5;
int n;
ll ans,lcmk,a[maxn],p[maxn];
inline ll gcd(ll a,ll b){
	if (!b) return a;
	return gcd(b,a%b);
}
inline void exgcd(ll a,ll b,ll &x,ll &y){
	if (!b){
		x=1,y=0;
		return ;
	}
	exgcd(b,a%b,x,y);
	ll tmp=x;
	x=y,y=tmp-(a/b)*y;
}
inline ll solve(ll a,ll b,ll m){
	a=Mod(a,m);
	ll x,y,p=b/gcd(a,m);
	exgcd(a,m,x,y);
	x=Mod(x,m),p=Mod(p,m);
	return Mod(x*p,m);
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%lld%lld",&p[i],&a[i]);
	ans=solve(1,a[1],p[1]),lcmk=p[1];
	for (int i=2;i<=n;i++){
		ll t=solve(lcmk,Mod(a[i]-ans,p[i]),p[i]);
		ll lcmk2=lcmk/gcd(lcmk,p[i])*p[i];
		ans+=Mod(lcmk*t,lcmk2);
		ans=Mod(ans,lcmk2);
		lcmk=lcmk2;
	}
	printf("%lld\n",ans);
	return 0;
}

2023/4/29 11:30
加载中...