[算法] EXCRT 证明

初始值

{ x ≡ a ( m o d b ) x ≡ c ( m o d d ) } \begin{Bmatrix}x\equiv a \pmod{b}\\ x\equiv c\pmod{d}\end{Bmatrix} {xa(modb)xc(modd)}

证明

{ x = a + P b x = c + Q d } a + P b = c + Q d a − c = Q d − P b 令 t = gcd ⁡ ( b , d ) , 则 a − c t = Q d t − P b t a − c t ≡ Q d t ( m o d b t ) 问题就转化成     a x ≡ b ( m o d m ) 了。 我们求出这个     x , 即为     Q     代入     x = c + Q d     即可 \begin{Bmatrix} x=a+Pb\\ x=c+Qd\\ \end{Bmatrix}\\ a+Pb=c+Qd\\ a-c=Qd-Pb\\ 令t=\gcd(b,d),则\\ \frac{a-c}{t}=\frac{Qd}{t}-\frac{Pb}{t}\\ \frac{a-c}{t}\equiv Q\frac{d}{t} \pmod{\frac{b}{t}}\\ 问题就转化成\,\,\,ax\equiv b\pmod m 了。\\ 我们求出这个\,\,\,x ,即为\,\,\,Q\,\,\,\\ 代入\,\,\, x=c+Qd \,\,\,即可 {x=a+Pbx=c+Qd}a+Pb=c+Qdac=QdPbt=gcd(b,d),tac=tQdtPbtacQtd(modtb)问题就转化成axb(modm)了。我们求出这个x,即为Q代入x=c+Qd即可

代码

注意可能爆LL……

#include<bits/stdc++.h>
#define RI register int
using namespace std;typedef long long LL;const int inf=0x3fffffff;int CH,FL;template<typename T>bool in(T&a){for(CH=getchar(),FL=1,a=0;!isdigit(CH)&&CH!=EOF;CH=getchar())FL=(CH=='-')?-1:1;for(;isdigit(CH)&&CH!=EOF;CH=getchar())a=a*10+CH-'0';return a*=FL,CH!=EOF;}template<typename T,typename...Args>int in(T&a,Args&...args){return in(a)+in(args...);}
int n;
inline LL mul(LL a,LL b,LL mod){
	a=((a%mod)+mod)%mod;
	b=((b%mod)+mod)%mod;
	__int128 c=a;c*=b;c%=mod;
	return (LL)c;
}
void exgcd(LL a,LL b,LL&x,LL&y){
	if(b==0){x=1;y=0;return;}
	exgcd(b,a%b,x,y);
	int t=x;x=y;y=t-(a/b)*y;
}
inline LL inv(LL a,LL mod){
	a%=mod;(a+=mod)%=mod;
	LL x,y;
	exgcd(a,mod,x,y);
	return ((x%mod)+mod)%mod;
}
const int maxn=20001;
LL a[maxn],b[maxn];
inline LL lcm(LL a,LL b){
	return a/__gcd(a,b)*b;
}
void excrt(){
	LL A=a[1],B=b[1];
	for(RI i=2;i<=n;++i){
		LL t=__gcd(b[i],B);
		if((A-a[i])%t!=0){printf("No Answer\n");return;}
		A=A+mul(mul(inv(B/t,b[i]/t),(a[i]-A)/t,b[i]/t),B,lcm(B,b[i]));
		B=lcm(B,b[i]);
	}printf("%lld\n",A);
}
int main(){
	in(n);
	for(RI i=1;i<=n;++i)in(b[i],a[i]);
	excrt();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值