其实打了CRT和exCRT很多遍了打完就忘……后来发现是因为我老是看到一些写的极其复杂的博客……

模板题

现在有n个形如 \(x \equiv a_i \pmod {b_i}\) 的方程

假设前k-1个方程的最小正整数解是\(ans_{k-1},\)

\(M=gcd(b_1,b_2,……,b_{k-1})\)

\(ans_k=ans_{k-1}+xM(x为非负整数)\)

\(ans_{k-1}+xM \equiv a_k \pmod {b_k}\)

\(∴tx\equiv {{a_k}-{ans_{k-1}}} \pmod {b_k}\)

\(Mx+{b_k}y={{a_k}-{ans_{k-1}}}\)

exgcd。
题目的a,b读入是反的,注意。 还有记得开longlong。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n;
LL ans,M=1; 
LL gcd(LL x,LL y){ return y?gcd(y,x%y):x; } 
LL lcm(LL x,LL y){ return x*y/gcd(x,y); }
LL exgcd(LL A,LL B,LL &x,LL &y){
	if(!B){ x=1,y=0;return x; }
	else{
		LL d=exgcd(B,A%B,y,x);
		y-=A/B*x;return d;
	}
} 
void crt(LL A,LL B){
	LL a=M,b=B,c=((A-ans)%B+B)%B,x,y;
	LL g=exgcd(a,b,x,y);
	if(c%g) return;
	x=((x*(c/g))%B+B)%B;ans+=x*M;
	M=lcm(M,B);ans=(ans%M+M)%M;
} 
int main(){
	scanf("%d",&n);
	LL a,b;
	for(int i=1;i<=n;i++)
		scanf("%lld%lld",&a,&b),crt(b,a);
	printf("%lld\n",ans);
	return 0;
}

相关文章:

  • 2022-01-27
  • 2021-09-27
  • 2021-09-23
  • 2021-11-09
  • 2022-12-23
  • 2021-12-01
  • 2021-07-27
  • 2022-12-23
猜你喜欢
  • 2021-09-12
  • 2021-09-09
  • 2021-10-23
  • 2022-12-23
  • 2021-11-21
  • 2021-07-13
  • 2022-01-29
相关资源
相似解决方案