solution:
毒瘤题。
注意我们只关注同余方程有解即可。
根据题意得到
a
i
+
p
i
∗
y
=
A
T
K
∗
x
i
a_i+p_i*y=ATK*x_i
a i + p i ∗ y = A T K ∗ x i
化简得到
A
T
K
∗
x
i
≡
a
i
(
m
o
d
p
i
)
ATK*x_i\equiv a_i\pmod {p_i}
A T K ∗ x i ≡ a i ( m o d p i ) ,这个式子等价于
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)}}
A T K ≡ b i ( m o d ( p i , x i ) p i ) ,其中
b
i
b_i
b i 是满足
b
i
∗
x
i
≡
a
i
(
m
o
d
p
i
)
b_i*x_i\equiv a_i\pmod {p_i}
b i ∗ x i ≡ a i ( m o d p i ) 的最小非负整数解。
把上面的式子扔进 excrt 即可。注意
p
i
=
1
p_i=1
p i = 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 ;
}
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;
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 ();
}
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」