简略题意:
给出
a
a
, ,
c
c
和,
x2
x
2
,
y1
y
1
,
y2
y
2
, 问满足
ax+by+c=0
a
x
+
b
y
+
c
=
0
的
x
x
和的对数有多少。
首先把输入处理成 ax+by=c a x + b y = c 的形式,且 a,b,c a , b , c 都为 0 0 或正数。
然后分类讨论分别是 0 0 的情况,这些比较简单。
对于和
b
b
都不是的情况,可以用扩展欧几里德来求出一组特解
x0,y0
x
0
,
y
0
。
易知道通解的
x
x
和与特解的关系分别对应:
x=x0+b/Gcd(a,b)∗t
x
=
x
0
+
b
/
G
c
d
(
a
,
b
)
∗
t
y=y0−a/Gcd(a,b)∗t(其中t为任意整数)
y
=
y
0
−
a
/
G
c
d
(
a
,
b
)
∗
t
(
其
中
t
为
任
意
整
数
)
那么在合法的区间内,满足要求的
k
k
<script type="math/tex" id="MathJax-Element-337">k</script>的个数就是答案。
需要特别注意左端点向上取整,右端点向下取整,并且负数的取整方法和正数不同…
#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
#define eps 1e-16
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
void umax(int &a, int b) {
a = max(a, b);
}
void umin(int &a, int b) {
a = min(a, b);
}
int dcmp(double x) {
return fabs(x) <= eps?0:(x > 0?1:-1);
}
void file() {
freopen("data_in.txt", "r", stdin);
freopen("data_out.txt", "w", stdout);
}
namespace solver {
LL floor(LL x, LL y) {
if(x >= 0) return x / y;
return (x - y + 1) / y;
}
LL ceil(LL x, LL y) {
if(x >= 0) return (x + y - 1) / y;
return x / y;
}
LL a, b, c, x1, x2, y1, y2;
void no_solution() {
puts("0");
exit(0);
}
void ex_gcd(LL a, LL b, LL &d, LL &x, LL &y) {
if(b == 0) {
x = 1, y = 0, d = a;
return ;
}
ex_gcd(b, a%b, d, y, x);
y -= a/b*x;
}
void solve() {
scanf("%lld%lld%lld", &a, &b, &c);
c = -c;
scanf("%lld%lld%lld%lld", &x1, &x2, &y1, &y2);
if(c < 0) a = -a, b = -b, c = -c;
if(a < 0) {
a = -a;
x1 = -x1, x2 = -x2;
swap(x1, x2);
}
if(b < 0) {
b = -b;
y1 = -y1, y2 = -y2;
swap(y1, y2);
}
if(a == 0 && b == 0) {
if(c == 0) printf("%lld\n", (y2-y1+1)*(x2-x1+1));
else
no_solution();
return ;
}
if(a == 0) {
if(c % b == 0) {
LL v = c / b;
if(v <= y2 && v >= y1) cout<<x2-x1+1<<endl;
else puts("0");
return ;
} else
no_solution();
}
if(b == 0) {
if(c % a == 0) {
LL v = c / a;
if(v <= x2 && v >= x1) cout<<y2-y1+1<<endl;
else puts("0");
return ;
} else
no_solution();
}
LL g, x, y;
ex_gcd(a, b, g, x, y);
if(c % g) no_solution();
LL t = c / g;
x *= t, y *= t;
a /= g, b /= g;
LL al = ceil((x1 - x), b);
LL ar = floor((x2 - x), b);
LL bl = ceil((y - y2), a);
LL br = floor((y - y1), a);
cout<<max(0LL, min(ar, br) - max(al, bl) + 1)<<endl;
}
}
//2 2 -6 0 4 0 4
int main() {
// file();
solver::solve();
return 0;
}