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

 注意加快速乘,防止整数溢出。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mx=1e5+5;
int n;
ll a[mx],m[mx];
ll fmul(ll x,ll y,ll z) {
	x%=z,y%=z; if(y<0) x=-x,y=-y;
	ll sum(0);
	for(;y;y>>=1) {
		if(y&1) sum=(sum+x)%z;
		x=(x+x)%z; 
	}
	return sum;
}
ll fpow(ll x,ll y,ll z) {
	x%=z;
	ll mul(1);
	for(;y;y>>=1) {
		if(y&1) mul=mul*x%z;
		x=x*x%z;
	}
	return mul;
}
void exgcd(ll &x,ll &y,ll a,ll b,ll &d) {
	if(b==0) {
		x=1,y=0,d=a;
	}
	else {
		exgcd(y,x,b,a%b,d);
		y-=x*(a/b);
	}
}
int main() {
	scanf("%d",&n);
	for(int i=1;i<=n;i++) {
		scanf("%lld%lld",&m[i],&a[i]);
	}
	bool flg(0);
	for(int i=2;i<=n;i++) {
		ll tmp=((a[i]-a[1])%m[i]+m[i])%m[i];
		ll k1,k2,d; exgcd(k1,k2,m[1],m[i],d);
		if(tmp%d) {
			flg=1;break;
		}
		k1=(fmul(k1,tmp/d,m[i]/d)+(m[i]/d))%(m[i]/d);
		ll M=m[1]/d*m[i];
		a[1]=(a[1]+fmul(m[1],k1,M))%M;
		m[1]=M;
	}
	printf("%lld",a[1]);
}
中国剩余定理:
 记  
     
      
       
       
         M 
        
       
         = 
        
        
        
          ∏ 
         
         
         
           i 
          
         
           = 
          
         
           1 
          
         
        
          n 
         
        
        
        
          m 
         
        
          i 
         
        
       
      
        M=\prod_{i=1}^nm_i 
       
      
    M=∏i=1nmi , 
     
      
       
        
        
          M 
         
        
          i 
         
        
       
         = 
        
        
        
          M 
         
         
         
           m 
          
         
           i 
          
         
        
       
      
        M_i=\frac{M}{m_i} 
       
      
    Mi=miM ,则  
     
      
       
       
         a 
        
       
         n 
        
       
         s 
        
       
         = 
        
        
        
          ∑ 
         
         
         
           i 
          
         
           = 
          
         
           1 
          
         
        
          n 
         
        
        
        
          M 
         
        
          i 
         
        
        
        
          M 
         
        
          i 
         
         
         
           − 
          
         
           1 
          
         
        
        
        
          a 
         
        
          i 
         
        
       
      
        ans=\sum_{i=1}^nM_iM_i^{-1}a_i 
       
      
    ans=∑i=1nMiMi−1ai 是模  
     
      
       
       
         M 
        
       
      
        M 
       
      
    M 意义下原同余方程组的解。其中  
     
      
       
        
        
          M 
         
        
          i 
         
         
         
           − 
          
         
           1 
          
         
        
       
      
        M_i^{-1} 
       
      
    Mi−1 是模  
     
      
       
        
        
          m 
         
        
          i 
         
        
       
      
        m_i 
       
      
    mi 意义下的逆元。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mx=1005;
int n;
ll M,res,a[mx],m[mx];
ll fpow(ll x,ll y,ll z) {
	x%=z;
	ll mul(1);
	for(;y;y>>=1) {
		if(y&1) mul=mul*x%z;
		x=x*x%z;
	}
	return mul;
}
void exgcd(ll &x,ll &y,ll a,ll b) {
	if(b==0) {
		x=1,y=0;
	}
	else {
		exgcd(y,x,b,a%b);
		y-=x*(a/b);
	}
}
int main() {
	scanf("%d",&n); M=1;
	for(int i=1;i<=n;i++) {
		scanf("%lld%lld",&m[i],&a[i]);
		M=M*m[i];
	}
	for(int i=1;i<=n;i++) {
		ll mi=M/m[i],x,y;
		exgcd(x,y,mi,m[i]); x=(x%m[i]+m[i])%m[i];
		res=(res+a[i]*mi*x%M)%M;
	}
	printf("%lld",res);
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号