先考虑只有两个方程怎么做。
满足 x≡r1(modm1),x≡r2(modm2)
相当于 x≡ans(modlcm(m1,m2))
把方程放进同余方程组就相当于合并了两个方程。
CF 710D
给你 a1,a2,b1,b2,l,r ,
问有多少个 l≤x≤r,x=a1∗k′+b1=a2∗l′+b2 ,满足 k′,l′ 是非负整数。
#include
#include
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#define db double
using namespace std;
ll m1,m2,r1,r2,l,r;
ll ans1,ans2;
ll exgcd(ll a,ll b,ll &x,ll &y){
if (b==0) {
x=1;
y=0;
return a;
}
ll ret=exgcd(b,a % b,x,y),tmp=y;
y=x-a / b*y;
x=tmp;
return ret;
}
void Ex_crt(){
ans1=m1;
ans2=r1;
ll x,y,gcd;
gcd=exgcd(ans1,m2,x,y);
if ((r2-ans2) % gcd) {
ans1=-1;
return;
}
ll lcm=ans1/ gcd*m2;
x=x*(r2-ans2)/ gcd;
y=y*(r2-ans2)/ gcd;
ll add=m2 / gcd;
x=(x % add+add) % add;
ans2=lcm;
ans1=r1+x*m1;
ans1=(ans1 % ans2+ans2) % ans2;
}
int main(){
cin>>m1>>r1>>m2>>r2>>l>>r;
//x=r1 (%m1)
//x=r2 (%m2)
Ex_crt();
l=max(l,max(r1,r2));
if (ans1==-1 || l>r) {
puts("0");
return 0;
}
ll ans;
ans=floor((db)(r-ans1)/ans2)-floor((db)(l-ans1)/ans2);
if ((l-ans1) % ans2==0) ans++;
printf("%I64d",ans);
return 0;
}