Rylynnn SGU106

文章目录

原题

题意

满足

ax+by+c = 0

的x和y在(x1,x2)和(y1,y2)范围内的有多少组解

分析

照旧c放到方程右边,然后首先要分类讨论

1.a==0 && b==0
2.a==0 && b!=0
3.a!-0 && b==0
4.a!=0 && b!=0

对第四种情况,用扩展欧几里得,然后将x1,x2,y1,y2带入求出t的范围,然后取重合区间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <cstdio>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
ll (ll a,ll b) {
return b==0?a:gcd(b,a%b);
}
void exgcd(ll a,ll b,ll& x,ll& y) {
if(b==0) {
x=1,y=0;
return;
}
exgcd(b,a%b,x,y);
ll temp=x;
x=y;
y=temp-a/b*y;
return;
}
int main() {
ll a,b,c,x1,x2,y1,y2,x,y,t,num,k1,k2,k3,k4;
while(scanf("%I64d%I64d%I64d",&a,&b,&c)!=EOF) {
scanf("%I64d%I64d%I64d%I64d",&x1,&x2,&y1,&y2);
if(a==0&&b==0) {
if(c==0) {
printf("%I64dn",(x2-x1+1)*(y2-y1+1));
}
else {
printf("0n");
}
}
else if(a==0&&b!=0) {
if(c%b==0&&(c/b)>=y1&&(c/b)<=y2) {
printf("%I64dn",x2-x1+1);
}
else {
printf("0n");
}
}
else if(b==0&&a!=0) {
if(c%a==0&&(c/a)>=x1&&(c/a)<=x2) {
printf("%I64dn",y2-y1+1);
}
else {
printf("0n");
}
}
else {
t=gcd(a,b);
c=-c;
num=0;
if(c%t!=0) {
printf("0n");
}
else {
a/=t;
b/=t;
c/=t;
exgcd(a,b,x,y);
x*=c;
y*=c;
k1=(x1-x);
k2=(x2-x);
k3=(y-y1);
k4=(y-y2);

if(k1%b==0||k1<=0){
k1=k1/b;
}
else{
k1=k1/b+1;
}
if(k2%b==0||k2>=0){
k2=k2/b;
}
else{
k2=k2/b-1;
}
if(k3%a==0||k3>=0){
k3=k3/a;
}
else{
k3=k3/a-1;
}
if(k4%a==0||k4<=0){
k4=k4/a;
}
else{
k4=k4/a+1;
}
if(k2<=k1){
int temp=k1;
k1=k2;
k2=temp;
}
if(k4<=k3){
int temp=k3;
k3=k4;
k4=temp;
}//cout<<k1<<' '<<k2<<' '<<k3<<' '<<k4<<' ';
printf("%I64dn",min(k4,k2)-max(k1,k3)+1);
}
}
}
return 0;
}