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.
Examples
Input
2 0 3 3 5 21
Output
3
Input
2 4 3 0 6 17
Output
2
题解:给出两个式子 分别是 a1 * l + b1 、 a2 * k + b2。存在 x 属于 [L,R],是的 x = a1 * l + b1 = a2 * k + b2。
题目思路:一开始暴力计算第一个位于区间内的交点,然后通过数学计算区间内符合条件的x的个数,这个做法 TLE18;
之后听了学长的讲题,一开始不会用拓展中国剩余定理(拓展欧几里得),但是听了学长的思路,我尝试先找第一个公共交点再去计算区间中符合条件的x的个数,这个做法TLE22。
然后我就去学了拓展中国剩余定理(哭。。。。,虽然不会算拓展中国剩余定理的复杂度,但是相比于我的暴力做法肯定要优化的多的。
拓展中国剩余定理,我就不在乱讲了,毕竟自己都不是很会呢。。(哭。。。
贴一篇大佬的博客
https://www.cnblogs.com/zwfymqz/p/8425731.html
这个博客讲的很清楚的啦!跟着步骤走基本都能看懂
贴一下题解的代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int maxn = 200030; ll a1,a2,b1,b2,L,R; ll ans = 0; int gcd(int a,int b){ if(b == 0) return a; else return gcd(b,a%b); } int lcm(int a,int b){ return a*b/gcd(a,b); } void exgcd(ll a,ll b,ll &x,ll &y) { if (!b) x=1,y=0; else exgcd(b,a%b,y,x),y-=a/b*x; } ll inv(ll a,ll b) { ll x=0,y=0; exgcd(a,b,x,y); x=(x%b+b)%b; if (!x) x+=b; return x; } int main(){ cin>>a1>>b1>>a2>>b2>>L>>R; L = max(L,max(b1,b2));// 因为l和k>=0,所以这里更新边界 if(b1 > R || b2 > R){ printf("0 "); return 0; }//因为 x 必定大于等于max(b1,b2),当 x 大于右边界的时候,无解 if(a1 < a2){ swap(a1,a2); swap(b1,b2); } b1 = b1%a1; b2 = b2%a2; ll t = gcd(a1,a2); if((b2 - b1)%t){ printf("0 "); return 0; }// (b2 - b1)%t != 0 这种情况下,不存在 x 使得两式相等 ll b = ((inv(a1/t,a2/t)) * (b2 - b1)/t)%(a2/t)*a1 + b1;// 拓展中国剩余定理 ll a = lcm(a1,a2); if(b < L){ ans = (R - b)/a - (L - b)/a; if((L - b)%a == 0) ans++; }else if(b > R){ ans = (b - L)/a - (b - R)/a; if((b - R)%a == 0) ans++; }else ans=(R-b)/a+(b-L)/a+1; printf("%lld",ans); return 0; } //2 -5 3 -4 -7 21
有一种情况,就是当两个式子永远都不可能相等的时候,就是 (b2 %a2- b1%a1)%t != 0,这个时候就不会存在解了。拓展中国剩余定理所计算的结果就是0,然而这却不是正确的解,这代表相同点不存在。
一个从很久以前就开始做的梦。