题目
数据范围
题解
直接求每个
⌊
T
−
B
[
i
]
A
[
i
]
⌋
\lfloor\frac{T-B[i]}{A[i]}\rfloor
⌊A[i]T−B[i]⌋不是很容易。
突破口:①
A
i
A_i
Ai的范围很小。考虑将
A
i
A_i
Ai相同的归为一类。
②此题具有二分性质。随着T增大,
S
(
T
)
S(T)
S(T)不会减小。可以二分。
③带下取整符号的式子不好直接快速求值,尝试将下取整符号删除。
问题转化成求
S
(
T
)
S(T)
S(T)
考虑将
A
i
A_i
Ai相同的归为一类,相当于固定住了
A
i
A_i
Ai。
设n对数
(
A
i
,
B
i
)
(A_i,B_i)
(Ai,Bi)中,
A
a
1
=
A
a
2
=
A
a
3
=
.
.
.
=
A
a
k
=
x
A_{a1}=A_{a2}=A_{a3}=...=A_{ak}=x
Aa1=Aa2=Aa3=...=Aak=x
那么x对
S
(
T
)
S(T)
S(T)的贡献为:
∑
i
=
1
k
⌊
T
−
B
a
i
x
⌋
=
∑
i
=
1
k
(
T
x
−
B
a
i
x
)
−
⌊
(
B
a
i
−
T
)
%
x
x
⌋
\sum_{i=1}^k\lfloor\frac{T-B_{ai}}{x}\rfloor=\sum_{i=1}^k(\frac{T}{x}-\frac{B_{ai}}{x})-\lfloor\frac{(B_{ai}-T)\%x}{x}\rfloor
i=1∑k⌊xT−Bai⌋=i=1∑k(xT−xBai)−⌊x(Bai−T)%x⌋
随着
B
a
i
B_{ai}
Bai的增大,
B
a
i
≥
T
B_{ai}\geq T
Bai≥T的
a
i
a_i
ai的数量也会不减少。
然而修改操作让我们不能直接对这么多个
(
A
i
,
B
i
)
(A_i,B_i)
(Ai,Bi)中相同
A
i
A_i
Ai的数对,按照
B
i
B_i
Bi从小到大排序。
A
i
<
=
1000
A_i<=1000
Ai<=1000?不需要按照
B
i
B_i
Bi排序,直接存个和模
A
i
A_i
Ai有关的前缀和就好了。
假设
B
a
1
,
B
a
2
,
.
.
.
,
B
a
k
B_{a1},B_{a2},...,B_{ak}
Ba1,Ba2,...,Bak中,有p个
≥
T
%
x
\geq T\%x
≥T%x。
则x对
S
(
T
)
S(T)
S(T)的贡献为:
∑
i
=
1
k
(
T
x
−
B
a
i
x
)
−
q
\sum_{i=1}^k(\frac{T}{x}-\frac{B_{ai}}{x})-q
i=1∑k(xT−xBai)−q
心得
①范围小的,可尝试分分类。
②带下取整符号的式子不好直接快速求值,尝试将下取整符号删除。
③如果花费不多的时间预处理一种信息,同时可以用很小的时间复杂度去维护预处理的信息,那么可以考虑预处理这一种信息。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 100010
#define M 1010
#define LL long long
#define P(a) putchar(a)
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct note{
LL op,x,y,id;
};note qu[N];
LL i,j,k,l,r,n,m,S,T;
LL op,x,y,delta;
LL L,R,mid,ans,last,temp,mx;
LL a[N],b[N];
LL a1[M][M];
LL cz[M][2];
bool pp;
LL read(){
LL res=0,fh=1;char ch;
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')fh=-1,ch=getchar();
while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
return res*fh;
}
void write(LL x){
if(x>9)write(x/10);
P(x%10+'0');
}
bool cmp(note x,note y){return x.x<y.x;}
int main(){
T=read();
while(T--){
memset(a1,0,sizeof(a1));
memset(cz,0,sizeof(cz));
n=read();m=read();
fo(i,1,n)a[i]=read();
mx=0;
fo(i,1,n){
b[i]=read();
cz[a[i]][0]+=b[i]/a[i];
cz[a[i]][1]++;
mx=max(mx,a[i]);
temp=b[i]%a[i];
a1[a[i]][temp]++;
}
fo(i,1,mx)fo(j,1,i)a1[i][j]+=a1[i][j-1];
fo(i,1,m){
qu[i].op=read();
if(qu[i].op<3){
qu[i].x=read(),qu[i].y=read();
} else qu[i].x=read();
qu[i].id=i;
}
fo(i,1,m){
if(qu[i].op==3){
L=0,ans=R=1000000000000;
while(L<R){
mid=(L+R)>>1;
S=0;
fo(j,1,mx)S+=cz[j][1]*(mid/j)-cz[j][0]-a1[j][j]+a1[j][mid%j];
if(S>=qu[i].x)ans=R=mid;else L=mid+1;
}
write(ans),P('\n');
} else
if(qu[i].op==1){
x=qu[i].x,y=qu[i].y;
cz[a[x]][0]-=b[x]/a[x];cz[a[x]][1]--;
fo(j,b[x]%a[x],a[x])a1[a[x]][j]--;
a[x]=y;mx=max(mx,y);
cz[a[x]][0]+=b[x]/a[x];cz[a[x]][1]++;
fo(j,b[x]%a[x],a[x])a1[a[x]][j]++;
} else{
x=qu[i].x,y=qu[i].y;
cz[a[x]][0]+=y/a[x]-b[x]/a[x];
l=b[x]%a[x],r=y%a[x],delta=-1;
if(l>r)swap(l,r),delta=1;
fo(j,l,r-1)a1[a[x]][j]+=delta;
b[x]=y;
}
}
}
return 0;
}