【模板】扩展中国剩余定理(EXCRT)

Code: 

#include <cstdio> 
#include <algorithm>      
#define N 100005   
#define ll long long  
#define ull unsigned long long 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;  
int n;      
ll arr[N],brr[N]; 
ll mult(ll x,ll y,ll mod) 
{
	ll tmp=(long double)x/mod*y;   
	return ((ull)x*y-(ull)tmp*mod+mod)%mod;  
}
ll qpow(ll base,ll k,ll mod) 
{
	ll tmp=1; 
	for(;k;k>>=1,base=mult(base,base,mod)) if(k&1) tmp=mult(tmp,base,mod); 
	return tmp;   
} 
ll exgcd(ll a,ll b,ll &x,ll &y) 
{
	if(!b) 
	{
		x=1,y=0; 
		return a;     
	}
	ll gcd=exgcd(b,a%b,x,y),tmp=x;            
	x=y,y=tmp-a/b*y;                    
	return gcd;   
}
ll Excrt() 
{ 
	int i,j; 
	ll ans=brr[1],M=arr[1];  
	for(i=2;i<=n;++i) 
	{    
		ll a=M,b=arr[i],x,y,c=brr[i]-ans,gcd;
		gcd=exgcd(a,b,x,y),b=abs(b/gcd);
		x=mult(x,c/gcd,b);                 
		ans+=M*x;
		M*=arr[i]/gcd;                                      
		ans=(ans%M+M)%M;         
	}
	return ans;
}
int main() 
{ 
	int i,j;  
	// setIO("input"); 
	scanf("%d",&n);  
	for(i=1;i<=n;++i) scanf("%lld%lld",&arr[i],&brr[i]);  
	printf("%lld\n",Excrt()); 
	return 0; 
}

  

posted @ 2018-10-26 14:59  EM-LGH  阅读(240)  评论(0编辑  收藏  举报