SGU106
上高数课的时候在看数论,后来闲着无聊就想这个题,回来后就写掉了.
方法很简单,先把方程化为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 <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;
}
头晕,一堆的条件语句,最怕阅读代码了