SGU 106 扩展欧几里得 不定方程
2014-04-18 17:19
288 查看
题目链接点这儿
题目还是不长。。。我就搬过来了。。。
这题。。。好坑啊有木有。。。
我们先用扩展欧几里得求得tx, ty满足atx + bty = gcd(a,b)
然后ax+by=-c的通解便为(首先要c|d)x = tx + i * b / d, y = ty - i * a/d(这里x y 是一组解,i是整数,证明可以将原不定方程两边取模,然后blablabla)
剩下的就是求这个范围内i的最小值和最大值,作差即可。
谁告诉我扩展欧几里得不能求负数的= =。。。结果一开始还写了点让a, b, c都保持正的语句。。。结果。。。wa到死。。。T^T
下面放出代码⊙▽⊙
#include <bits/stdc++.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a))
#define rep(i,initial_n,end_n) for(int (i)=(initial_n);(i)<(end_n);i++)
#define repp(i,initial_n,end_n) for(int (i)=(initial_n);(i)<=(end_n);(i)++)
#define reep(i,initial_n,end_n) for((i)=(initial_n);(i)<(end_n);i++)
#define reepp(i,initial_n,end_n) for((i)=(initial_n);(i)<=(end_n);(i)++)
#define eps 1.0e-9
#define MAX_N 1010
using namespace std;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef __int64 ll;
typedef unsigned __int64 ull;
#include <bits/stdc++.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a))
#define rep(i,initial_n,end_n) for(int (i)=(initial_n);(i)<(end_n);i++)
#define repp(i,initial_n,end_n) for(int (i)=(initial_n);(i)<=(end_n);(i)++)
#define reep(i,initial_n,end_n) for((i)=(initial_n);(i)<(end_n);i++)
#define reepp(i,initial_n,end_n) for((i)=(initial_n);(i)<=(end_n);(i)++)
#define eps 1.0e-9
#define MAX_N 1010
using namespace std;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef __int64 ll;
typedef unsigned __int64 ull;
ll exgcd(ll a, ll b, ll &x, ll &y);
int main() {
ll a, b, x1, x2, y1, y2, c;
scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d", &a, &b, &c, &x1, &x2, &y1, &y2);
c = -c;
if(a == 0 && b == 0) {
if(c == 0) printf("%I64d\n", (x2-x1+1) * (y2-y1+1));
else puts("0");
exit(0);
}
if(a == 0) {
if(c%b == 0 && y1 <= c/b && y2 >= c/b) printf("%I64d\n", x2 - x1 + 1);
else puts("0");
exit(0);
}
if(b == 0) {
if(c%a == 0 && x1 <= c/a && x2 >= c/a) printf("%I64d\n", y2 - y1 + 1);
else puts("0");
exit(0);
}
ll tx = 0, ty = 0, d = exgcd(a, b, tx, ty);
if(c%d) { puts("0"); exit(0); }
tx = tx * (c/d), ty = ty * (c/d);
ll i_lx = (x1 <= tx || (x1-tx) * d % b == 0 ? (x1-tx) * d / b : (x1-tx) * d / b + 1),
i_rx = (x2 >= tx || (x2-tx) * d % b == 0 ? (x2-tx) * d / b : (x2-tx) * d / b - 1),
i_ly = (y1 <= ty || (y1-ty) * d % a == 0 ? (ty-y1) * d / a : (ty-y1) * d / a - 1),
i_ry = (y2 >= ty || (y2-ty) * d % a == 0 ? (ty-y2) * d / a : (ty-y2) * d / a + 1);
if(i_lx > i_rx) swap(i_lx, i_rx);
if(i_ly > i_ry) swap(i_ly, i_ry);
ll ansl = max(i_lx, i_ly), ansr = min(i_rx, i_ry);
if(ansl <= ansr) printf("%I64d\n", ansr - ansl + 1);
else puts("0");
return 0;
}
ll exgcd(ll a, ll b, ll &x, ll &y) {
if(b == 0) {
x = 1, y = 0;
return a;
}
else {
ll r = exgcd(b, a%b, y, x);
y -= x*(a/b);
return r;
}
}
题目还是不长。。。我就搬过来了。。。
time limit per test: 0.25 sec. memory limit per test: 4096 KB There is an equation ax + by + c = 0. Given a,b,c,x1,x2,y1,y2 you must determine, how many integer roots of this equation are satisfy to the following conditions : x1<=x<=x2, y1<=y<=y2. Integer root of this equation is a pair of integer numbers (x,y). Input Input contains integer numbers a,b,c,x1,x2,y1,y2 delimited by spaces and line breaks. All numbers are not greater than 108 by absolute value. Output Write answer to the output. Sample Input 1 1 -3 0 4 0 4 Sample Output 4 |
我们先用扩展欧几里得求得tx, ty满足atx + bty = gcd(a,b)
然后ax+by=-c的通解便为(首先要c|d)x = tx + i * b / d, y = ty - i * a/d(这里x y 是一组解,i是整数,证明可以将原不定方程两边取模,然后blablabla)
剩下的就是求这个范围内i的最小值和最大值,作差即可。
谁告诉我扩展欧几里得不能求负数的= =。。。结果一开始还写了点让a, b, c都保持正的语句。。。结果。。。wa到死。。。T^T
下面放出代码⊙▽⊙
#include <bits/stdc++.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a))
#define rep(i,initial_n,end_n) for(int (i)=(initial_n);(i)<(end_n);i++)
#define repp(i,initial_n,end_n) for(int (i)=(initial_n);(i)<=(end_n);(i)++)
#define reep(i,initial_n,end_n) for((i)=(initial_n);(i)<(end_n);i++)
#define reepp(i,initial_n,end_n) for((i)=(initial_n);(i)<=(end_n);(i)++)
#define eps 1.0e-9
#define MAX_N 1010
using namespace std;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef __int64 ll;
typedef unsigned __int64 ull;
#include <bits/stdc++.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a))
#define rep(i,initial_n,end_n) for(int (i)=(initial_n);(i)<(end_n);i++)
#define repp(i,initial_n,end_n) for(int (i)=(initial_n);(i)<=(end_n);(i)++)
#define reep(i,initial_n,end_n) for((i)=(initial_n);(i)<(end_n);i++)
#define reepp(i,initial_n,end_n) for((i)=(initial_n);(i)<=(end_n);(i)++)
#define eps 1.0e-9
#define MAX_N 1010
using namespace std;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef __int64 ll;
typedef unsigned __int64 ull;
ll exgcd(ll a, ll b, ll &x, ll &y);
int main() {
ll a, b, x1, x2, y1, y2, c;
scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d", &a, &b, &c, &x1, &x2, &y1, &y2);
c = -c;
if(a == 0 && b == 0) {
if(c == 0) printf("%I64d\n", (x2-x1+1) * (y2-y1+1));
else puts("0");
exit(0);
}
if(a == 0) {
if(c%b == 0 && y1 <= c/b && y2 >= c/b) printf("%I64d\n", x2 - x1 + 1);
else puts("0");
exit(0);
}
if(b == 0) {
if(c%a == 0 && x1 <= c/a && x2 >= c/a) printf("%I64d\n", y2 - y1 + 1);
else puts("0");
exit(0);
}
ll tx = 0, ty = 0, d = exgcd(a, b, tx, ty);
if(c%d) { puts("0"); exit(0); }
tx = tx * (c/d), ty = ty * (c/d);
ll i_lx = (x1 <= tx || (x1-tx) * d % b == 0 ? (x1-tx) * d / b : (x1-tx) * d / b + 1),
i_rx = (x2 >= tx || (x2-tx) * d % b == 0 ? (x2-tx) * d / b : (x2-tx) * d / b - 1),
i_ly = (y1 <= ty || (y1-ty) * d % a == 0 ? (ty-y1) * d / a : (ty-y1) * d / a - 1),
i_ry = (y2 >= ty || (y2-ty) * d % a == 0 ? (ty-y2) * d / a : (ty-y2) * d / a + 1);
if(i_lx > i_rx) swap(i_lx, i_rx);
if(i_ly > i_ry) swap(i_ly, i_ry);
ll ansl = max(i_lx, i_ly), ansr = min(i_rx, i_ry);
if(ansl <= ansr) printf("%I64d\n", ansr - ansl + 1);
else puts("0");
return 0;
}
ll exgcd(ll a, ll b, ll &x, ll &y) {
if(b == 0) {
x = 1, y = 0;
return a;
}
else {
ll r = exgcd(b, a%b, y, x);
y -= x*(a/b);
return r;
}
}
相关文章推荐
- SGU 106 The equation 扩展欧几里得好题
- SGU 106 The equation (GCD·我所理解的扩展欧几里得)
- The equation - SGU 106(扩展欧几里得)
- sgu106 扩展欧几里得
- 数论 + 扩展欧几里得 - SGU 106. The equation
- SGU 106 The Equation 扩展欧几里得应用
- SGU 106 The equation【扩展欧几里得】
- 数论 + 扩展欧几里得 - SGU 106. The equation
- SGU - 106 - The equation (扩展欧几里得)
- SGU 106 The equation【扩展欧几里得】
- SGU 106 扩展欧几里得
- SGU 106 The equation ----扩展欧几里得
- sgu106(扩展欧几里得)
- SGU 106 The equation(扩展欧几里得)
- SGU 106 The equation(扩展欧几里得)
- 扩展欧几里德 SGU 106
- 【HDU 3037】大数组合取模之Lucas定理+扩展欧几里得求逆元与不定方程一类问题
- 扩展欧几里德 SGU 106
- SGU 106 The equation(扩展欧几里德)
- SGU 141 Jumping Joe(扩展欧几里得)