SGU - 106 The equation(扩欧+细节处理)
传送门
题目大意
给出 a x + b y + c = 0 ax+by+c=0 ax+by+c=0这一二元一次不定方程,求满足 { ( x , y ) ∣ x ∈ [ l x , r x ] , y ∈ [ l y , r y ] } \{(x,y) | x \in [lx,rx],y\in [ly,ry]\} {(x,y)∣x∈[lx,rx],y∈[ly,ry]}解的个数。
解题思路
自以为写了不少扩欧的题目,已经了如指掌,可是这道题又再次打脸, w a wa wa到怀疑人生…
首先不难想到如果 c c c挪到等式右边仍然是负数那么应该将 c c c变号,与此同时 a , b a,b a,b也应该变号,但是此时 a , b a,b a,b的符号可能是负的。一开始我的想法是将符号提到自变量 x , y x,y x,y处,即 ∣ a ∣ ( − x ) + ∣ b ∣ ( − y ) = c |a|(-x)+|b|(-y)=c ∣a∣(−x)+∣b∣(−y)=c,然后求出特解后直接取负。这样的做法不可以吗?可以,但是在本题是不行的,原因如下:
因为我们要求的是在给定解空间下的解的个数,假设不考虑 a , b a,b a,b的符号那么上述方程化为 x = c − b y a x = \frac{c-by}{a} x=ac−by,当 a a a的符号改变后直接影响了最后的通解的形式发生改变,因此如果我们想对 a a a取负,正确的做法是对给出的解空间取反,也就是变成了 [ − r x , − l x ] [-rx,-lx] [−rx,−lx],对于 y y y同理。
然后就是当我们解出通解后,需要得到解的个数,因为 x , y x,y x,y的变换是相反的,看起来似乎很难下手,但是实际上我们只需要根据通解的这个不等式 l x ≤ x 0 + k 1 b g c d ( a , b ) ≤ r x lx \leq x_0+k_1\frac{b}{gcd(a,b)} \leq rx lx≤x0+k1gcd(a,b)b≤rx求出 x x x在解空间下 k 1 k_1 k1的取值范围,然后和 y y y的 k 2 k_2 k2的取值范围,二者取一个交集即可。此时需要再次注意,左边应该向上取整,右边向下取整,画个图就明白了。
还有就是需要特判 a = 0 , b = 0 a=0,b=0 a=0,b=0的三种情况
//
// Created by Happig on 2020/10/30
//
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define Vector Point
#define ENDL "\n"
#define lowbit(x) (x&(-x))
#define mkp(x, y) make_pair(x,y)
#define mem(a, x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
const double eps = 1e-8;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double dinf = 1e300;
const ll INF = 1e18;
const int Mod = 1e9 + 7;
const int maxn = 2e5 + 10;ll exgcd(ll a, ll b, ll &x, ll &y) {if (!b) {x = 1, y = 0;return a;}ll d = exgcd(b, a % b, y, x);y -= a / b * x;return d;
}ll gcd(ll a, ll b) {return b == 0 ? a : gcd(b, a % b);
}int main() {//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);//ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);ll a, b, c, lx, rx, ly, ry;cin >> a >> b >> c >> lx >> rx >> ly >> ry;c = -c;if (c < 0) c = -c, a = -a, b = -b;if (a < 0) a = -a, swap(lx, rx), lx = -lx, rx = -rx;if (b < 0) b = -b, swap(ly, ry), ly = -ly, ry = -ry;if (a == 0 && b == 0) {if (c == 0) cout << (rx - lx + 1) * (ry - ly + 1) << endl;else cout << 0 << endl;return 0;} else if (a == 0) {if (c % b == 0 && ly <= c / b && c / b <= ry) cout << rx - lx + 1 << endl;else cout << 0 << endl;return 0;} else if (b == 0) {if (c % a == 0 && lx <= c / a && c / a <= rx) cout << ry - ly + 1 << endl;else cout << 0 << endl;return 0;}ll d = gcd(a, b);if (c % d) {cout << "0" << endl;} else {ll x, y;exgcd(a, b, x, y);x = x * c / d, y = y * c / d;//cout << x << " " << y << endl;a /= d, b /= d;int l = max(ceil(1.0 * (lx - x) / b), ceil(1.0 * (y - ry) / a)), r = min(floor(1.0 * (rx - x) / b),floor(1.0 * (y - ly) / a));if (r >= l) cout << r - l + 1 << endl;else cout << 0 << endl;}return 0;
}
SGU - 106 The equation(扩欧+细节处理)相关推荐
- sgu 106 The equation ★★(线性方程ax+by=c限制区间的解)
题目大意:给定a,b,c,x1,x2,y1,y2,求满足a*x+b*y+c = 0的解x满足x1<=x<=x2,y满足y1<=y<=y2.求满足条件的解的个数. 题目链接:ht ...
- POJ2142-The Balance【扩欧】
前言 感谢x某q的帮助 这是它的博客(只有找本人才会解释的博客): https://blog.csdn.net/sugar_free_mint/article/details/80755188 正题 ...
- bzoj3122 [Sdoi2013]随机数生成器(bsgs+扩欧+数列)
Description Input 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数. 接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据.保证X1和t都是合法的页码. 注意 ...
- jzoj1158-荒岛野人【扩欧,gcd,同余方程】
正题 大意 有n个野人,每个野人有一个初始山洞CiCiC_i,每次向前移动距离PiPiP_i,寿命LiLiL_i,如果野人走到了最后一个山洞那么继续就好回到第一个山洞,求至少多少个山洞才可以让野人们不 ...
- P1082-扩欧模板同余方程【扩欧,数论】
正题 链接: https://www.luogu.org/record/show?rid=7914999 大意 就是 ax≡1(modb)ax≡1(modb) ax≡1(modb) 给出a和b求x 解 ...
- SGU 141 Jumping Joe(扩展欧几里得)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=141 题意:给出x1,x2,P,K,求一组非负整数解(p1,n1,p2,n2)满足: ...
- P1516-青蛙的约会【扩欧,同余方程】
#正题 链接: https://www.luogu.org/record/show?rid=7935281 ##大意 两只青蛙往相同方向绕圈,A蛙一次跳n米在x出发,B蛙一次跳m米在y出发,一圈长度L ...
- POJ2115-C Looooops【扩欧,同余】
正题 链接: http://poj.org/problem?id=2115 大意 就是给出个循环 for(i=A;i!=B;i=(i+C)mod2k)for(i=A;i!=B;i=(i+C)mod2k ...
- (扩)欧几里得的一些见解
a x + b y = g c d ( a , b ) g c d ( a , b ) = g c d ( b , a % b ) 首 先 证 明 上 面 这 个 柿 子 假 设 d = g c d ...
最新文章
- 测试Animation大型动画文件拆分播放的可行性
- MALTLAB 求出水仙花数
- (转载)H.264码流的RTP封包说明
- oracle删表分区同时维护索引,有关Oracle表分区进行(DML)维护后对索引的影响的分析...
- r怎么对两组数据统计检验_数据科学中最常用的统计检验是什么
- 高质量的设计素材,有效提高工作效率
- 2017/08/03 工作日志
- vs2013 命名空间“Microsoft.Office”中不存在类型或命名空间名称“Interop”。是否缺少程序集引用?...
- 拓端tecdat:R语言贝叶斯广义线性混合效应(多层次/水平/嵌套)模型GLMM、逻辑回归分析教育留级影响因素数据
- 一级计算机第65套题,全国计算机一级考试题库(附答案).pdf
- love2d与imgui
- 计算机职业适应性测试题库,职业适应性测试题库 一、性格职业适应度测试.doc...
- 面试常见的 10 大问题
- TFT和STN液晶区别
- vue 项目中页面打印实现(去除页眉页脚)
- HDU 6608 FansBlog(粉丝博客)(MillerRabin算法+威尔逊算法)
- JS中事件的绑定和解绑
- KindEditor编辑器上传修改拿shell漏洞
- wchar_t的用法
- 具有自适应边界与最优引导的莱维飞行蚁狮优化算法-附代码