Description
Solution
将题意转化成方程:
对于每一个方程,我们可以用扩欧解出来,得到一个解
和解的间隔
,那么就可以将原方程转化成:
然后两两合并、求解即可。
同步赛上有个东西忘记清零然后炸成70了QAQ
Code
/************************************************
* Au: Hany01
* Prob: dragon
* Email: [email protected]
* Inst: Yali High School
************************************************/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i)
#define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define x first
#define y second
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) ((int)(a).size())
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define y1 wozenmezhemecaia
template <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
inline LL read() {
static LL _, __; static char c_;
for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1;
for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
return _ * __;
}
const int maxn = 100005;
multiset<LL> Set;
struct Equation { LL c, m; }Eq[maxn];
int n, m, bk, N;
LL a[maxn], p[maxn], rew[maxn], t[maxn], A, B, C, t1, t2, Gcd, k, X, Y, d;
LL gcd(LL x, LL y, LL& a, LL& b)
{
if (!x) { a = 0, b = 1; return y; }
register LL ret = gcd(y % x, x, a, b),t = a;
a = b - a * (y / x);
b = t;
return ret;
}
LL mult(LL a, LL b, LL MOD) {
if (a < 0 && b < 0) a = -a, b = -b;
if (b < 0) a = -a, b = -b;
LL Ans = 0;
for ( ; b; b >>= 1, (a <<= 1) %= MOD) if (b & 1) (Ans += a) %= MOD;
return Ans;
}
int main()
{
File("dragon");
for (static int T = read(); T --; )
{
n = read(), m = read(), Set.clear(), bk = 0;
For(i, 1, n) a[i] = read();
For(i, 1, n) p[i] = read();
For(i, 1, n) rew[i] = read();
For(i, 1, m) Set.insert(read());
For(i, 1, n) {
if (*Set.begin() >= a[i]) t[i] = *Set.begin(), Set.erase(Set.begin());
else {
multiset<LL>::iterator it = --Set.upper_bound(a[i]);
t[i] = *it, Set.erase(it);
}
Set.insert(rew[i]);
}
N = 0;
For(i, 1, n) {
if (p[i] == 1) continue;
LL Gcd = __gcd(t[i], p[i]);
A = t[i], B = p[i], C = a[i];
if (C % (Gcd = __gcd(A, B))) { bk = 1; break; }
k = C / Gcd, gcd(A, B, X, Y);
d = p[i] / __gcd(p[i], t[i]);
X = mult(X, k, d);
Eq[++ N].c = X, Eq[N].m = d;
}
if (bk) { puts("-1"); continue; }
Fordown(i, N, 2) {
A = Eq[i - 1].m, B = -Eq[i].m, C = Eq[i].c - Eq[i - 1].c;
if (C % (Gcd = __gcd(A, B))) { bk = 1; break; }
k = C / Gcd, gcd(A, B, t1, t2);
LL t = Eq[i - 1].m;
Eq[i - 1].m = Eq[i - 1].m / __gcd(Eq[i - 1].m, Eq[i].m) * Eq[i].m;
t1 = mult(t1, k, Eq[i - 1].m);
Eq[i - 1].c = (mult(t1, t, Eq[i - 1].m) + Eq[i - 1].c) % Eq[i - 1].m;
}
if (bk) { puts("-1"); continue; }
if (N) ((Eq[1].c %= Eq[1].m) += Eq[1].m) %= Eq[1].m;
else Eq[1].m = 1, Eq[1].c = 0;
For(i, 1, n)
if (Eq[1].c * t[i] < a[i]) {
Eq[1].c += (a[i] - Eq[1].c * t[i]) / t[i] / Eq[1].m * Eq[1].m;
if (Eq[1].c * t[i] < a[i]) Eq[1].c += Eq[1].m;
}
printf("%lld\n", Eq[1].c);
}
return 0;
}
//叹江山如故,千村寥落。
// -- 岳飞《满江红·登黄鹤楼有感》