解线性同余方程组,且方程仅2个,另外得到的x限制在L,R区间内,
观察一下A1K-A2L=B2-B1,便可知,通解(K,L)中会同时增大或同时减小,大可以先使得K,L大于等于0,于是之后只需要考虑让K不断增大且这样得到的x在[L,R]内即可。
由x在[L,R]中,便可以求出K的范围,然后分情况讨论一下就好了。
#include <cmath> #include <cstdio> #include <cstdlib> #include <cassert> #include <cstring> #include <set> #include <map> #include <list> #include <queue> #include <string> #include <iostream> #include <algorithm> #include <functional> #include <stack> #include <bitset> using namespace std; typedef long long ll; #define INF (0x3f3f3f3f) #define maxn (1000005) #define mod 1000000007 #define ull unsigned long long ll a1,b1,a2,b2,L,R; ll exgcd(ll a,ll b,ll& x,ll& y){ if(b == 0){ x = 1,y = 0; return a; } ll g = exgcd(b,a % b,x,y),t = x; x = y; y = t - a/b*y; return g; } void solve(){ ll A = a1,B = a2,C = b2 - b1,x,y; ll g = exgcd(A,B,x,y); if(C % g != 0){ puts("0"); return; } x = C/g*x; ll t = B/g; if(x < 0) x = x + (abs(x)/t + 1) * t; x = x - (x/t)*t; //x为最小非负数 y = (a1*x+b1-b2)/a2; if(y < 0){//令x,y均大于等于0 y = y + (A/g)*(abs(y)/(A/g) + 1); y = y - (y/(A/g))*(A/g); x = (a2*y+b2-b1)/a1; } ll l = (L - b1)/a1,r = (R-b1)/a1,ans;//l <= x <= r if(L-b1>=0&&(L-b1)%a1!=0)++l; if(R-b1<0&&(R-b1)%a1!=0)--r; if(x < l){ ans = ans + (r-x)/t-(l-x)/t + 1; if((l-x)%t != 0) ans--; } else if(x <= r) ans = (r - x)/t + 1; else ans = 0; printf("%lld ",ans); } int main() { //printf("%d",-1/2); scanf("%lld%lld%lld%lld%lld%lld",&a1,&b1,&a2,&b2,&L,&R); solve(); return 0; }