solution:
毒瘤题。
注意我们只关注同余方程有解即可。
根据题意得到 a i + p i ∗ y = A T K ∗ x i a_i+p_i*y=ATK*x_i ai+pi∗y=ATK∗xi
化简得到 A T K ∗ x i ≡ a i ( m o d p i ) ATK*x_i\equiv a_i\pmod {p_i} ATK∗xi≡ai(modpi) ,这个式子等价于 A T K ≡ b i ( m o d p i ( p i , x i ) ) ATK\equiv b_i\pmod {\frac{p_i}{(p_i,x_i)}} ATK≡bi(mod(pi,xi)pi) ,其中 b i b_i bi 是满足 b i ∗ x i ≡ a i ( m o d p i ) b_i*x_i\equiv a_i\pmod {p_i} bi∗xi≡ai(modpi) 的最小非负整数解。
把上面的式子扔进 excrt 即可。注意 p i = 1 p_i=1 pi=1 特判。
时间复杂度 O(Tn(loglcm+logn)) 。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define PII pair<int,int>
#define PIII pair<int,PII>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int mx=1e5+5;
int n,q;
ll a[mx],m[mx],t[mx],p[mx],ad[mx];
multiset<ll> s;
ll gcd(ll x,ll y) {
return y==0?x:gcd(y,x%y);
}
ll fmul(ll x,ll y,ll z) {
x%=z,y%=z; if(y<0) x=-x,y=-y;
ll sum(0);
for(;y;y>>=1) {
if(y&1) sum=(sum+x)%z;
x=(x+x)%z;
}
return sum;
}
ll lcm(ll x,ll y) {
if(x==0||y==0) return x^y;
return x/gcd(x,y)*y;
}
void exgcd(ll &x,ll &y,ll a,ll b,ll &d) {
if(b==0) {
x=1,y=0,d=a;
}
else {
exgcd(y,x,b,a%b,d);
y-=x*(a/b);
}
}
bool excrt() {
for(int i=1;i<=n;i++) {
if(a[i]>=m[i]) return 1;
}
for(int i=2;i<=n;i++) {
ll tmp=((a[i]-a[1])%m[i]+m[i])%m[i];
ll k1,k2,d; exgcd(k1,k2,m[1],m[i],d);
if(tmp%d) return 1;
k1=(fmul(k1,tmp/d,m[i]/d)+(m[i]/d))%(m[i]/d);
ll M=m[1]/d*m[i];
a[1]=(a[1]+fmul(m[1],k1,M))%M;
m[1]=M;
}
return 0;
}
void solve() {
ll tmp(0);
for(int i=1;i<=n;i++) {
auto it=s.upper_bound(t[i]);
if(it!=s.begin()) it--;
ll x=*it; s.erase(it); s.insert(ad[i]);
if(t[i]%gcd(x,p[i])) {
printf("-1\n");
return;
}
//求解 x*k1=a (mod p[i]) 的最小非负整数
//k1 周期为 p[i]/gcd(p[i],x)
ll k1,k2,d; exgcd(k1,k2,x,p[i],d);
ll mo=p[i]/d;
k1=(fmul(k1,t[i]/d,mo)+mo)%mo;
//等价转化为 ATK=k1 (mod p[i]/d)
m[i]=mo;
a[i]=k1;
if(m[i]==1) tmp=max(tmp,(t[i]+x-1)/x);
}
if(excrt()) {
printf("-1\n");
return;
}
a[1]=max(a[1],tmp);
printf("%lld\n",a[1]);
return;
}
signed main() {
int T; scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&q); s.clear();
for(int i=1;i<=n;i++) {
scanf("%lld",&t[i]);
}
for(int i=1;i<=n;i++) {
scanf("%lld",&p[i]);
}
for(int i=1;i<=n;i++) {
scanf("%lld",&ad[i]);
}
for(int i=1;i<=q;i++) {
ll x; scanf("%lld",&x);
s.insert(x);
}
solve();
}
}