题意:
解法:
操 作 3 显 然 是 二 分 , 但 是 c h e c k 是 O ( n = 1 e 5 ) 的 , 顶 不 住 . 操作3显然是二分,但是check是O(n=1e5)的,顶不住. 操作3显然是二分,但是check是O(n=1e5)的,顶不住.
观 察 到 a ( i ) 的 取 值 只 有 1000 , 考 虑 合 并 a ( i ) 相 同 的 位 置 . 观察到a(i)的取值只有1000,考虑合并a(i)相同的位置. 观察到a(i)的取值只有1000,考虑合并a(i)相同的位置.
S ( t ) = ∑ i = 1 n ⌊ t − b i a i ⌋ S(t)=\sum_{i=1}^n \lfloor \frac{t-bi}{ai}\rfloor S(t)=∑i=1n⌊ait−bi⌋
令 t = k 1 ∗ a i + c 1 , b i = k 2 ∗ a i + c 2 令t=k1*ai+c1,bi=k2*ai+c2 令t=k1∗ai+c1,bi=k2∗ai+c2
那 么 S ( t ) = ∑ i = 1 n ⌊ k 1 ∗ a i + c 1 − k 2 ∗ a i − c 2 a i ⌋ 那么S(t)=\sum_{i=1}^n \lfloor \frac{k1*ai+c1-k2*ai-c2}{ai} \rfloor 那么S(t)=∑i=1n⌊aik1∗ai+c1−k2∗ai−c2⌋
= ∑ i = 1 n ⌊ k 1 ∗ a i − k 2 ∗ a i − ( c 2 − c 1 ) a i ⌋ =\sum_{i=1}^n \lfloor \frac{k1*ai-k2*ai-(c2-c1)}{ai} \rfloor =∑i=1n⌊aik1∗ai−k2∗ai−(c2−c1)⌋
固 定 t , 对 于 每 种 a ( i ) : 固定t,对于每种a(i): 固定t,对于每种a(i):
k 1 , c 1 可 以 直 接 计 算 , s u m ( k 2 ) , c n t ( c 2 ) 可 以 预 处 理 k1,c1可以直接计算,sum(k2),cnt(c2)可以预处理 k1,c1可以直接计算,sum(k2),cnt(c2)可以预处理
但 是 对 于 下 取 整 , 对 于 当 c 2 − c 1 > 0 的 时 ( 即 c 2 > c 1 ) , 贡 献 会 减 少 1 但是对于下取整,对于当c2-c1>0的时(即c2>c1),贡献会减少1 但是对于下取整,对于当c2−c1>0的时(即c2>c1),贡献会减少1
因 此 还 需 要 记 录 对 于 每 一 种 c 1 , 当 前 有 多 少 个 c 2 大 于 它 , 这 个 可 以 预 处 理 因此还需要记录对于每一种c1,当前有多少个c2大于它,这个可以预处理 因此还需要记录对于每一种c1,当前有多少个c2大于它,这个可以预处理
此 外 还 需 要 预 处 理 每 组 a i 的 数 量 s z [ a [ i ] ] 此外还需要预处理每组ai的数量sz[a[i]] 此外还需要预处理每组ai的数量sz[a[i]]
然 后 就 能 将 c h e c k 优 化 为 O ( 1000 ) 的 了 , 不 会 超 时 然后就能将check优化为O(1000)的了,不会超时 然后就能将check优化为O(1000)的了,不会超时
code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e6+5;
const int mod=998244353;
int cntC2[1005][1005];
int sumK2[1005];
int sz[1005];
int a[maxm];
int b[maxm];
int n,m;
int ppow(int a,int b,int mod){
int ans=1%mod;a%=mod;
for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;
return ans;
}
int S(int t){
int ans=0;
for(int i=1;i<=1000;i++){
int K1=t/i;
int C1=t%i;
int temp=K1*sz[i]-sumK2[i];
temp-=cntC2[i][C1+1];
ans+=temp;
}
return ans;
}
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
for(int i=1;i<=1000;i++){
sumK2[i]=0;
sz[i]=0;
for(int j=0;j<1000;j++){
cntC2[i][j]=0;
}
}
for(int i=1;i<=n;i++){
sumK2[a[i]]+=b[i]/a[i];
cntC2[a[i]][b[i]%a[i]]++;
sz[a[i]]++;
}
for(int i=1;i<=1000;i++){
for(int j=1000-1;j>=0;j--){
cntC2[i][j]+=cntC2[i][j+1];//cnt[i][j]表示>=j的数量
}
}
while(m--){
int op;cin>>op;
if(op==1){
int x,y;cin>>x>>y;
sz[a[x]]--;
sumK2[a[x]]-=b[x]/a[x];
for(int i=b[x]%a[x];i>=0;i--){
cntC2[a[x]][i]--;
}
a[x]=y;
sz[a[x]]++;
sumK2[a[x]]+=b[x]/a[x];
for(int i=b[x]%a[x];i>=0;i--){
cntC2[a[x]][i]++;
}
}else if(op==2){
int x,y;cin>>x>>y;
sz[a[x]]--;
sumK2[a[x]]-=b[x]/a[x];
for(int i=b[x]%a[x];i>=0;i--){
cntC2[a[x]][i]--;
}
b[x]=y;
sz[a[x]]++;
sumK2[a[x]]+=b[x]/a[x];
for(int i=b[x]%a[x];i>=0;i--){
cntC2[a[x]][i]++;
}
}else if(op==3){
int k;cin>>k;
int l=0,r=1e9;
int ans=-1;
while(l<=r){
int mid=(l+r)/2;
int t=S(mid);
if(t>=k){
ans=mid,r=mid-1;
}else{
l=mid+1;
}
}
cout<<ans<<endl;
}
}
}
signed main(){
ios::sync_with_stdio(0);
int T=1;
cin>>T;
while(T--){
solve();
}
return 0;
}