Codevs 3990 [中国剩余定理]

时间:2023-03-09 03:17:53
Codevs 3990 [中国剩余定理]

模板题

注意如何得到[a,b]区间范围内的解

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=;
inline ll read(){
char c=getchar();ll x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
ll n,l,r;
ll m[N],a[N],M=;
void exgcd(ll a,ll b,ll &d,ll &x,ll &y){
if(b==) d=a,x=,y=;
else exgcd(b,a%b,d,y,x),y-=(a/b)*x;
}
ll Inv(ll a,ll p){
ll d,x,y;
exgcd(a,p,d,x,y);
return d==?(x+p)%p:-;
}
ll CRT(int n,ll *a,ll *m){
ll x=;
for(int i=;i<=n;i++){
ll w=M/m[i];
x=(x+a[i]*w%M*Inv(w,m[i]))%M;
}
return x;
}
int main(){
freopen("in","r",stdin);
n=read();l=read();r=read();
for(int i=;i<=n;i++) m[i]=read(),M*=m[i],a[i]=read();
ll x=CRT(n,a,m),sum=,mn=;
//printf("M %lld %lld\n",x,M); if(x<l) x*=(l-x-)/x+ +;//,printf("x %lld\n",x);
if(x<=r) sum=(r-x)/M+,mn=x;
printf("%lld\n%lld",sum,mn);
}