传送门


题目大意

给出 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​+k1​gcd(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(扩欧+细节处理)相关推荐

  1. 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 ...

  2. POJ2142-The Balance【扩欧】

    前言 感谢x某q的帮助 这是它的博客(只有找本人才会解释的博客): https://blog.csdn.net/sugar_free_mint/article/details/80755188 正题 ...

  3. bzoj3122 [Sdoi2013]随机数生成器(bsgs+扩欧+数列)

    Description Input 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数. 接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据.保证X1和t都是合法的页码. 注意 ...

  4. jzoj1158-荒岛野人【扩欧,gcd,同余方程】

    正题 大意 有n个野人,每个野人有一个初始山洞CiCiC_i,每次向前移动距离PiPiP_i,寿命LiLiL_i,如果野人走到了最后一个山洞那么继续就好回到第一个山洞,求至少多少个山洞才可以让野人们不 ...

  5. P1082-扩欧模板同余方程【扩欧,数论】

    正题 链接: https://www.luogu.org/record/show?rid=7914999 大意 就是 ax≡1(modb)ax≡1(modb) ax≡1(modb) 给出a和b求x 解 ...

  6. SGU 141 Jumping Joe(扩展欧几里得)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=141 题意:给出x1,x2,P,K,求一组非负整数解(p1,n1,p2,n2)满足: ...

  7. P1516-青蛙的约会【扩欧,同余方程】

    #正题 链接: https://www.luogu.org/record/show?rid=7935281 ##大意 两只青蛙往相同方向绕圈,A蛙一次跳n米在x出发,B蛙一次跳m米在y出发,一圈长度L ...

  8. 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 ...

  9. (扩)欧几里得的一些见解

    a x + b y = g c d ( a , b ) g c d ( a , b ) = g c d ( b , a % b ) 首 先 证 明 上 面 这 个 柿 子 假 设 d = g c d ...

最新文章

  1. 测试Animation大型动画文件拆分播放的可行性
  2. MALTLAB 求出水仙花数
  3. (转载)H.264码流的RTP封包说明
  4. oracle删表分区同时维护索引,有关Oracle表分区进行(DML)维护后对索引的影响的分析...
  5. r怎么对两组数据统计检验_数据科学中最常用的统计检验是什么
  6. 高质量的设计素材,有效提高工作效率
  7. 2017/08/03 工作日志
  8. vs2013 命名空间“Microsoft.Office”中不存在类型或命名空间名称“Interop”。是否缺少程序集引用?...
  9. 拓端tecdat:R语言贝叶斯广义线性混合效应(多层次/水平/嵌套)模型GLMM、逻辑回归分析教育留级影响因素数据
  10. 一级计算机第65套题,全国计算机一级考试题库(附答案).pdf
  11. love2d与imgui
  12. 计算机职业适应性测试题库,职业适应性测试题库 一、性格职业适应度测试.doc...
  13. 面试常见的 10 大问题
  14. TFT和STN液晶区别
  15. vue 项目中页面打印实现(去除页眉页脚)
  16. HDU 6608 FansBlog(粉丝博客)(MillerRabin算法+威尔逊算法)
  17. JS中事件的绑定和解绑
  18. KindEditor编辑器上传修改拿shell漏洞
  19. wchar_t的用法
  20. 具有自适应边界与最优引导的莱维飞行蚁狮优化算法-附代码

热门文章

  1. 暑期SMALE魔鬼训练day3
  2. Qt 完成图片的缩放拖动
  3. 在内网环境使用pip离线安装python包
  4. linux目录命令改目录名,Linux命令详解——文件和目录常用命令-linux修改文件名...
  5. 积分兑换商城系统运营手册
  6. c语言杨辉三角(输出10行)
  7. Ubuntu 如何启动 ssh 服务
  8. 网络推广有什么作用?如何做推广分析思维导图
  9. Git命令大全或者使用Git命令操作也是Git命令总结
  10. 深度学习方法(十七):word2vec算法原理(1):跳字模型(skip-gram) 和连续词袋模型(CBOW)