15 opts,本地样例有一个输出了负数,怀疑是哪里long long 溢出了(但是检查了很多次,应该开 __int128的地方都开了)
#include <bits/stdc++.h>
#define int long long
#define LL __int128
using namespace std;
const int N = 1e5 + 100;
int n, k, ned;
int m[N], nw[N], r[N], c[N];
// c[i] · x = r[i] (mod m[i])
void exgcd(int a , int b , int &g , int &x , int &y){
if(!b){g = a , x = 1 , y = 0;return ;}
exgcd(b , a % b , g , y , x);
y -= a / b * x;
}
pair<int, int> merge(int r1, int m1, int r2, int m2){
int p, q, g;
exgcd(m1, m2, g, p, q);
if((r2 - r1) % g) return make_pair(-1, -1);
int t = m2 / g;
p = (LL)(p * ((r2 - r1) / g)) % t;
pair<int, int> ret = make_pair(m1 * p + r1, m1 * t);
ret.first = (ret.first % ret.second + ret.second) % ret.second;
return ret;
}
int inv(int a, int p){
int x, y, g;
exgcd(a, p, g, x, y);
if(g != 1) return -1;
return x;
}
int find(int x, int mn, int p){int ex = mn / p * p + x;if(ex < mn) ex += x;return ex;}
int excrt(){
int iv, m1, r1;
iv = inv(c[1], m[1]);
if(iv == -1) return -1;
r1 = (LL)iv * r[1] % m[1], m1 = m[1];
for(int i = 2;i <= n;i++){
iv = inv(c[i], m[i]);
if(iv == -1) return -1;
pair<int, int> u = merge(r1, m1, (LL)iv * r[i] % m[i], m[i]);
if(u.first == -1) return -1;
r1 = u.first, m1 = u.second;
}
return find(r1, ned, m1);
}
int fl(int x, int y){return (x - 1) / y + 1;}
signed main(){
freopen("in.txt","r",stdin);
int cas;scanf("%lld",&cas);while(cas--){
ned = 0;
multiset <int> st;
assert(st.empty());
scanf("%lld%lld",&n,&k);
for(int i = 1;i <= n;i++) scanf("%lld",&r[i]);
for(int i = 1;i <= n;i++) scanf("%lld",&m[i]);
for(int i = 1;i <= n;i++) scanf("%lld",&nw[i]);
for(int i = 1, x;i <= k;i++){
scanf("%lld", &x);
st.insert(x);
}
for(int i = 1;i <= n;i++){
auto u = st.upper_bound(r[i]);
if(u != st.begin()) u--;
c[i] = *u;
ned = max(ned, fl(r[i], c[i]));
r[i] = r[i] % m[i];
st.erase(u), st.insert(nw[i]);
}
printf("%lld\n",excrt());
}
}