[NOI2018] 屠龙勇士
题意
求解下列同余方程组,
其中,
Solution
不难发现,此方程组和exCRT模板有异曲同工之妙,尝试用相同的办法进行化简
考虑到exCRT的解产生的同余方程不带有前缀系数,考虑如下同余方程组,
展开得,
该式子左侧类似裴蜀定理, 则存在
当
当
则特解
考虑由多个同余方程组成的方程组,上面通解可表达成
由此,从原方程组中依次选出一个同余方程进行合并,显然不失一般性。
考虑第一组方程如何求解,显然存在
Code
点击查看代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <cmath>
using namespace std;
const int N = 1e5 + 50;
typedef long long lld;
inline lld read() {
register lld w = 0, f = 1;
register char c = getchar();
while (c > '9' || c < '0') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
w = w * 10 + c - '0';
c = getchar();
}
return w * f;
}
multiset <lld> S;
int n, M;
lld m[N], a[N], b[N], atk[N];
inline lld gcd(lld a, lld b) {
return !b ? a : gcd(b, a % b);
}
inline lld exgcd(register lld a, register lld b, lld &x, lld &y) {
if (!b) {
x = 1;
y = 0;
return a;
}
register lld d = exgcd(b, a % b, x, y);
register lld tmp = x;
x = y;
y = tmp - a / b * y;
return d;
}
inline lld mul(register lld a, register lld b, register lld p) {
lld ans = 0;
while (b) {
if (b & 1) ans = (ans + a) % p;
a = (a + a) % p;
b >>= 1;
}
return ans;
}
lld a1, m1;
int main() {
int T = read();
while (T--) {
bool allone = 1;
n = read(), M = read();
S.clear();
for (register int i = 1; i <= n; ++i) a[i] = read();
for (register int i = 1; i <= n; ++i) {
m[i] = read();
if (m[i] != 1) allone = 0;
}
for (register int i = 1; i <= n; ++i) atk[i] = read();
for (register int i = 1; i <= M; ++i) {
register lld x = read();
S.insert(x);
}
for(int i = 1; i <= n; ++i) {
auto u = S.upper_bound(a[i]);
if(u != S.begin()) u--;
b[i] = *u;
S.erase(u);
S.insert(atk[i]);
}
if (allone) {
register lld maxa = 0;
for (register int i = 1; i <= n; ++i) maxa = max(maxa, (lld)ceil(1.0 * a[i] / b[i]));
printf("%lld\n", maxa);
continue;
}
a1 = 0;
m1 = 1;
for (register int i = 1; i <= n; ++i) {
lld x, y;
lld g = exgcd(mul(b[i], m1, m[i]), m[i], x, y);
x = (x % m[i] + m[i]) % m[i];
lld C = (a[i] - mul(b[i], a1, m[i]) + m[i]) % m[i];
if (C % g != 0) {
printf("-1\n");
goto ed;
}
lld tmp = m[i] / g * m1;
a1 = (a1 + mul(mul(C / g, x, m[i] / g), m1, tmp)) % tmp;
m1 = tmp;
}
printf("%lld\n", a1);
ed:;
}
return 0;
}
后记
最近写数学题全是bug🤮🤮🤮
希望过几天手能够更稳一点吧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】