You are given two arithmetic progressions: a1k + b1 and a2l + b2. Find the number of integers x such that L ≤ x ≤ R and x = a1k’ + b1 = a2l’ + b2, for some integers k’, l’ ≥ 0.
Input
The only line contains six integers a1, b1, a2, b2, L, R (0 < a1, a2 ≤ 2·109, - 2·109 ≤ b1, b2, L, R ≤ 2·109, L ≤ R).
Output
Print the desired number of integers x.
题意: x = a1k’ + b1 = a2l’ + b2, 有L ≤ x ≤ R ,且k’, l’ ≥ 0。问符合条件 的x 有多少个。
a1k- a2l = b2-b1; 求出一组(k,l),并求出第一组解(k0>=0,l0>=0),此时对应一个最小的x。 通解为 k = k0 + -a2/gcd(a1,-a2)t , 则 x = a1(k0 + -a2/gcd(a1,-a2)*t ) + b1;
可以发现 x增值 为 -a1*a2/gcd(a1,-a2) = lcm(a1,a2),所以求出第一个x点后,在算区间有多少个 lcm就好。
#include <bits\stdc++.h>
using namespace std;
typedef long long LL;
LL ex_gcd(LL a,LL b,LL &x,LL &y){
if (b==0){
x=1,y=0;
return a;
}
LL q=ex_gcd(b,a%b,y,x);
y-=a/b*x;
return q;
}
void minial(LL& x, LL& y,LL k1, LL k2){
LL t = x/k1;
x -= t*k1, y -= t*k2;
if( x < 0){
x += k1, y+=k2;
}
// cout<<x<<" "<<y<<endl;
if( y < 0){
t = y/k2;
x -= t*k1, y -= t*k2;
if( y < 0){
x += k1, y+=k2;
}
}
}
LL cal(LL l, LL r, LL lcm){
if(l > r) return 0;
LL ans = (r-l)/lcm + 1;
return ans;
}
int main(){
LL a1,b1,a2,b2,l,r;
scanf("%lld %lld %lld %lld %lld %lld",&a1,&b1,&a2,&b2,&l,&r);
LL ans = 0, x, y;
if(b2 < b1) {
swap(b2,b1);
swap(a1,a2);
}
LL A = a1, B = -a2 , C= b2-b1; // a1x - a2y = b2-b1;
long long gcd = ex_gcd(A,B,x,y); // Ax + By = C
if(gcd < 0){
gcd = -gcd, x = -x, y = -y;
}
if(C%gcd !=0){
printf("0\n");
return 0;
}
else{
x = C/gcd*x, y = C/gcd*y; // 一组解
LL k1 = B/gcd, k2 = A/gcd;
if(k1<0) k1 = -k1;
if(k2<0) k2 = -k2;
minial(x,y,k1,k2); // 第一组 x>=0 y >=0 的解
LL d = a1*x + b1;
ans = cal(d,r,A*k1) - cal(d,l-1,A*k1);
printf("%lld\n",ans);
}
return 0;
}