上高数课的时候在看数论,后来闲着无聊就想这个题,回来后就写掉了.

方法很简单,先把方程化为ax+by=c,把ab=0的情况先处理掉,然后用扩展gcd算法得出ax+by=g(其中g = gcd(a,b))的一组解(x0, y0)。

若g|c,则有解,否则ans = 0。有解时另d=c/g,则(d*x0, d*y0)即原方程的一组解

通解可表示为 (d*x0 + k * b/d, d*y0 - k*a/d),然后根据x和y的范围限制,计算出k的范围即可得到答案。

其实此文的主要目的是再次测试一下发代码的效果

开始没注意到要用long long的问题,又wa了无数次,哎

#include <iostream>
#include <cmath>

using namespace std;

int a, b, c, x1, x2, Y1, Y2;
long long kmin = -300000000000000000LL, kmax=300000000000000000LL;
long long ans;

int gcd_extended(int a, int b, int &x, int &y){
    if (b == 0){
       x = 1; y = 0; return a;
    } else {
       int d = gcd_extended(b, a % b, x, y);
       int t = x; x = y; y = t - a / b * y;
       return d;
    }
}

long long upper(long long a, int b){
    if (a <= 0) return a / b;;
    return (a-1)/b+1;
}

long long lower(long long a, int b){
    if (a >= 0) return a / b;
    return (a+1)/b-1;
}

void update(long long L, long long R, int a){
    if (a < 0) {
        a=-a;L=-L;R=-R;
        swap(L,R);
    }
    kmin=max(kmin,upper(L,a));
    kmax=min(kmax,lower(R,a));
}

void solve(){
    int d, x, y;
    d = gcd_extended(a, b, x, y);
    if (c % d){
        ans = 0;
        return;
    }
    long long p = c / d;
    update(x1-p*x,x2-p*x,b/d);
    update(Y1-p*y,Y2-p*y,-a/d);
    ans = kmax - kmin + 1;
    if (ans < 0) ans = 0;
}

int main() {
    cin >> a>> b>> c>> x1>>x2>>Y1>>Y2;
    c = -c;
    if (a == 0 && b == 0){
        if (c == 0) ans = (long long)(x2-x1+1)*(Y2-Y1+1);
        else ans = 0;
    } else if (a == 0){
        int t = c / b;
        ans = (c%b==0 && t<=Y2 && t>=Y1) * (x2-x1+1);
    }
    else if (b == 0){
        int t = c / a;
        ans = (c%a==0 && t<=x2 && t>=x1) * (Y2-Y1+1);
    }
    else solve();

    cout << ans << endl;
    return 0;
}