T1
一些液体密度
ρ
i
(
1
≤
i
≤
n
)
\rho_i(1\le i\le n)
ρi(1≤i≤n),一些容器体积
v
i
(
1
≤
i
≤
n
)
v_i(1\le i\le n)
vi(1≤i≤n)
要求将液体装进容器里,求总质量的最小、最大值
发现排序后
m
a
x
=
∑
i
=
1
n
ρ
i
v
i
m
i
n
=
∑
i
=
1
n
ρ
i
v
n
−
i
+
1
max=\sum_{i=1}^n\rho_iv_i\\ min=\sum_{i=1}^n\rho_iv_{n-i+1}
max=i=1∑nρivimin=i=1∑nρivn−i+1
Θ
(
n
log
n
)
\Theta(n\log n)
Θ(nlogn)排序
考虑修改(考场上没有想到这一点)
找到数列中大小相同的一段,改最后和最前即可
想到排序记录映射:pos
原序列到排序序列,rnk
前者的逆映射
优化:直接二分
#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
int i=0,f=1;char ch=0;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') ch=getchar(),f=-1;
while(isdigit(ch)) i=(i<<3)+(i<<1)+ch-48,ch=getchar();
return i*f;
}
const int N=3e5+5;
int n,m;
int p[N],v[N],a[N],b[N];
long long maxx,minn;
void solve(int *s,int *t,int val,int d){
if(d>0){
int pos=upper_bound(s+1,s+n+1,val)-s-1;
++s[pos];
maxx+=t[pos];
minn+=t[n-pos+1];
}else{
int pos=lower_bound(s+1,s+n+1,val)-s;
--s[pos];
maxx-=t[pos];
minn-=t[n-pos+1];
}
return;
}
int main(){
n=in,m=in;
for(int i=1;i<=n;++i) p[i]=a[i]=in;
for(int i=1;i<=n;++i) v[i]=b[i]=in;
sort(a+1,a+n+1);
sort(b+1,b+n+1);
for(int i=1;i<=n;++i) maxx+=1ll*a[i]*b[i],minn+=1ll*a[i]*b[n-i+1];
printf("%lld %lld\n",minn,maxx);
for(int i=1;i<=m;++i){
int type=in-1,x=in,d=in;
if(!type) solve(a,b,p[x],d),p[x]+=d;
else solve(b,a,v[x],d),v[x]+=d;
printf("%lld %lld\n",minn,maxx);
}
return 0;
}