惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
腾讯CDC
D
Docker
G
Google Developers Blog
D
DataBreaches.Net
雷峰网
雷峰网
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
The Cloudflare Blog
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
量子位
美团技术团队
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解
26-4-24日志
Ghost-Face · 2026-04-24 · via 博客园_首页

Table of Contents

  1. 今日 Keyword:
  2. T1. P5656 【模板】二元一次不定方程 (exgcd).
    1. 题面
    2. WriteUp.
      1. Subtask1. 无解的判断.
      2. Subtask3/4. 有正整数解后/没有正整数解后..
      3. Subtask2. 有正整数解的判断.
      4. 整合&Code
  3. 今日总结:

Powered by Ghostface's Emacs.

P.S.今天是挑战150天冲击CSP-S 2026省一的第4天,目前阶段:数论.
离CSP-S 2026 还有147天.

“纵有疾风起,人生不言弃”.

今日 Keyword:

ExGCD.

T1. P5656 【模板】二元一次不定方程 (exgcd).

偶然发现还有这样的一道题可以做,遂决定先做一下。

题面

\[ax+by=c \]

  • 若该方程无整数解,输出 \(-1\)
  • 若该方程有整数解,且有正整数解,则输出其 正整数解 的数量、所有 正整数解 中 \(x\) 的最小值、所有 正整数解 中 \(y\) 的最小值、所有 正整数解 中 \(x\) 的最大值、以及所有 正整数解 中 \(y\) 的最大值。
  • 若方程有整数解,但没有正整数解,你需要输出所有 整数解 中 \(x\) 的最小正整数值, \(y\) 的最小正整数值。

第一行一个正整数 \(T\),代表数据组数。

接下来 \(T\) 行,每行三个由空格隔开的正整数 \(a, b, c\)

应输出 \(T\) 行。
若该行对应的询问无整数解,一个数字 \(-1\)
若该行对应的询问有整数解但无正整数解,包含 \(2\) 个由空格隔开的数字,依次代表整数解中,\(x\) 的最小正整数值,\(y\) 的最小正整数值。
否则包含 \(5\) 个由空格隔开的数字,依次代表正整数解的数量,正整数解中,\(x\) 的最小值,\(y\) 的最小值,\(x\) 的最大值,\(y\) 的最大值。

对于 \(100\%\) 的数据,\(1 \le T \le 2 \times {10}^5\)\(1 \le a, b, c \le {10}^9\)

WriteUp.

Subtask0 [拆分]:
易知这道题一共有4个Subtask,
Subtask1 : 无解的判断.
Subtask2 : 有正整数解的判断.
Subtask3 : 有正整数解后,求出解的数量、 \(x_{min/max}\)\(y_{min/max}\) .
Subtask4 : 没有正整数解后, \(x_{min},y_{min}\) .
让我们依次解决。

Subtask1. 无解的判断.

由前两天的推论(即贝祖定理 Bézout's identity ),易知该方程有解,当且仅当 \(\gcd{a,b} \mid c\) .
这是最简单的一个Subtask。Qef.

Subtask3/4. 有正整数解后/没有正整数解后.

为什么不先做Subtask2呢,因为实践证明,Subtask2需要用到Subtask3的结论。
根据「ExGCD解不定方程」的推论,设 \(x',y'\) 为不定方程 \(a'x + b'y = 1\) 的解,
\(g = gcd(a,b),c' = \frac{c}{g}\) ,则原方程存在特解 \(c'x,c'y\) .
记他们为 \(x_0,y_0\) .
接下来考虑如何求得通解,有了通解,分析增减性即可求出极值。

我们不妨设存在 \(m_x,m_y\) ,使得 \(a(x_0 + m_x) + b(y_0 + m_y) = c\) .
移项、化简得到 \(-\frac{a}{b}m_x =m_y\) .
\(m_x = b,m_y = a\) ,且两者符号相反,就满足条件。

但是这样不好分析,我们需要一个「步长」。
等式两边同时乘 \(k\) ,并且把符号的控制交给 \(k\) 来处理。
原式等价于 \(\frac{a}{b}km_x = -km_y\) .
此时令 \(m_x = b,m_y = a\) 就满足条件。

然而这不是最小的取值,这会导致, \(k\) 不能一个一个的变化,否则会丢解。
最小的取值是什么呢,很简单,再比上一个 \(\gcd{a,b}\) 就可以了。
因此,通解如下:

\[ \begin{cases} x = x_0 + k\frac{b}{\gcd{a,b}} \\ y = y_0 - k\frac{a}{\gcd{a,b}} \end{cases} \]

分析增减性可知,\(x\)\(y\) 的最值正好相反。
做一个取整把 \(k\) 求出来即可。

那么解的总数怎么求呢。
考虑,数轴上有若干个点,每 \(\frac{a}{\gcd{a,b}}\) 就出现一个,第一个点的坐标是 \(y_{min}\) ,最后一个点的坐标是 \(y_{max}\) .
试求出点的个数。这个问题的答案是显然的:
\(N = \frac{y_{max}-y_{min}}{\frac{a}{\gcd{a,b}}} + 1\) ,这也就是我们的答案。
另外的一个视角,因为k每变化1就会有一个新的点,所以, \(N = k_{max}-k_{min}+1\) .
至此,Subtask3 完成。Qef.
至于Subtask4,注意到Subtask3的结论同样适用,求此时的极值和刚才一模一样,同样也解决了。

Subtask2. 有正整数解的判断.

有了Subtask3的结论,这个问题就很简单了,当 \(y_{max} \lt 0\) 时,必定没有正整数解。
Qef.

整合&Code

我们集1、2、3、4之大成,隆重推出最终的Solution.

include

include

using namespace std;

typedef long long ll;

ll exgcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) {
x = 1, y = 0;
return a;
}
ll g = exgcd(b, a % b, y, x);
y -= (a / b) * x;
return g;
}

// 向上取整除法,b > 0
ll ceil_div(ll a, ll b) {
if (a >= 0) return (a + b - 1) / b;
else return a / b; // 因为 a/b 向零取整,对于负数恰好是向上取整
}

// 向下取整除法,b > 0
ll floor_div(ll a, ll b) {
if (a >= 0) return a / b;
else return (a - b + 1) / b;
}

int main() {
int T;
scanf("%d", &T);
while (T--) {
ll a, b, c;
scanf("%lld%lld%lld", &a, &b, &c);

ll x0, y0;
ll g = exgcd(a, b, x0, y0);

// 无整数解
if (c % g != 0) {
puts("-1");
continue;
}

// 特解 (x0, y0) 变为原方程的一组特解
x0 *= c / g;
y0 *= c / g;

ll dx = b / g; // x 的步长,正数
ll dy = a / g; // y 的步长,正数(注意通解中 y = y0 - k*dy)

// 求 k 的范围,使得 x > 0 且 y > 0
// x = x0 + kdx > 0 => k > -x0/dx
// y = y0 - k
dy > 0 => k < y0/dy
ll k_min = ceil_div(1 - x0, dx); // 最小的 k 使 x >= 1
ll k_max = floor_div(y0 - 1, dy); // 最大的 k 使 y >= 1

if (k_min <= k_max) {
// 有正整数解
ll cnt = k_max - k_min + 1; // 解的个数
ll x_min = x0 + k_min * dx;
ll y_max = y0 - k_min * dy;
ll x_max = x0 + k_max * dx;
ll y_min = y0 - k_max * dy;
printf("%lld %lld %lld %lld %lld\n", cnt, x_min, y_min, x_max, y_max);
} else {
// 没有正整数解,分别求最小的正整数 x 和最小的正整数 y
ll kx = ceil_div(1 - x0, dx);
ll x_pos = x0 + kx * dx;
ll ky = floor_div(y0 - 1, dy);
ll y_pos = y0 - ky * dy;
printf("%lld %lld\n", x_pos, y_pos);
}
}
return 0;
}

今日总结:

写日志的第三天,有我暑假训练的感觉了(x2)。
因为之前暑假的时候那次训练非常爽,虽然只有不到20天。
本来今天是要学组合数学的,但是因为学校放假耽误了一些时间,外加找到一个好题,就只好推迟到明天了。

“日拱一卒,功不唐捐”。

Upt 2026.4.24 20:45
ghostface