拓展欧几里得算法,ExGCD
exgcd用于计算,形如ax+by=c的解。
证明:参考:https://www.cnblogs.com/mrclr/p/9380300.html
1、利用exgcd求解ax0+by0=gcd(a,b)的一个解:

LL ExGCD(LL a, LL b, LL &x, LL &y) { if (b == 0) { x = 1; y = 0; return a; } LL xx, yy; LL gcd = ExGCD(b, a % b, xx, yy); x = yy; y = xx - yy * (a / b); return gcd; }
此函数返回值为gcd(a,b),x和y即为ax0+by0=gcd(a,b)的一个解
2、此时,可以得到ax+by=c的一个解:x1=x0*(c/gcd(a,b)),y1=y0*(c/gcd(a,b))
3、可以有结论,若要ax+by=c存在整数解,当且仅当c/gcd(a,b)为整数,即需要(gcd(a,b)|c)
4、可以得到,对于ax+by=c,令:x1=x0*(c/gcd(a,b)),y1=y0*(c/gcd(a,b)),
5、可得解集:
{(x, y) | x = x1 + k * b / gcd(a, b), y = y1 - k * a / gcd(a, b), k ∈ z}
例题:
https://codeforces.ml/contest/1728/problem/E
代码:

#include<bits/stdc++.h> #define fore(x,y,z) for(LL x=(y);x<=(z);x++) #define forn(x,y,z) for(LL x=(y);x<(z);x++) #define rofe(x,y,z) for(LL x=(y);x>=(z);x--) #define all(x) (x).begin(),(x).end() #define fi first #define se second using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; PLL ab[300010]; LL psuma[300010]; LL psumb[300010]; LL ExGCD(LL a, LL b, LL & x, LL & y) { if (b == 0) { x = 1; y = 0; return a; } LL xx, yy; LL gcd = ExGCD(b, a % b, xx, yy); x = yy; y = xx - yy * (a / b); return gcd; } void YD() { int n; cin >> n; fore(i, 1, n) cin >> ab[i].first >> ab[i].second; sort(ab + 1, ab + n + 1, [](PLL& x, PLL& y) { return x.first - x.second > y.first - y.second; }); for (int i = 1; i <= n; i++) { psuma[i] = psuma[i - 1] + ab[i].first; psumb[i] = psumb[i - 1] + ab[i].second; } int idx = 0; for (int i = 1; i <= n; i++) { if (ab[i].first - ab[i].second < 0) { idx = i; break; } } if (idx == 0) idx = n + 1; int cnta = idx-1; int cntb = n-cnta; int q; cin >> q; while (q--) { LL a, b; cin >> a >> b; LL x, y; LL gcd = ExGCD(a, b, x, y); if (n % gcd != 0) { cout << -1 << endl; continue; } x = x * n / gcd; y = y * n / gcd; double kd = (double(cnta) / a - x) * gcd / b; LL k = kd; LL k1 = k - 1,k2=k,k3=k+1; LL x1 = x + k1 * b / gcd, x2 = x + k2 * b / gcd, x3 = x + k3 * b / gcd; LL y1 = y - k1 * a / gcd, y2 = y - k2 * a / gcd, y3 = y - k3 * a / gcd; LL a1 = a * x1, a2 = a * x2, a3 = a * x3; LL b1 = b * y1, b2 = b * y2, b3 = b * y3; LL res1 = (a1 >= 0 && b1 >= 0) ?(psuma[a1]+psumb[n]-psumb[n-b1]) : -1; LL res2 = (a2 >= 0 && b2 >= 0) ? (psuma[a2] + psumb[n] - psumb[n - b2]) : -1; LL res3 = (a3 >= 0 && b3 >= 0) ? (psuma[a3] + psumb[n] - psumb[n - b3]) : -1; LL max_res = max({ res1, res2, res3 }); cout << max_res << endl; } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int T = 1; //cin >> T; while (T--) { YD(); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效