# [codeforces/gym/101350/L]维护“凸包”

（队友）观察发现，能盛的水的体积就等于这个容器的“凸包”的体积减去墙的体积。所以要做的就是动态的维护凸包。

#include<bits/stdc++.h>
using namespace std;
#define lson (i<<1)
#define rson (i<<1|1)

const int maxn=100005;
long long tree[maxn<<2];
int n;
int val[maxn];
int lz[maxn];
int len[maxn];

void push_up(int i)
{
tree[i]=tree[lson]+tree[rson];
}

void push_down(int i)
{
if (!lz[i]) return;
lz[lson]=lz[i];
lz[rson]=lz[i];
tree[lson]=1ll*lz[i]*len[lson];
tree[rson]=1ll*lz[i]*len[rson];
lz[i]=0;
}

void build(int l,int r,int i=1)
{
lz[i]=0;
if (l==r)
{
tree[i]=val[l];
len[i]=1;
}
else
{
int mid=(l+r)/2;
build(l,mid,lson);
build(mid+1,r,rson);
push_up(i);
len[i]=len[lson]+len[rson];
}
}

void setval(int l,int r,int x,int nowl,int nowr,int i=1)
{
if (l==nowl&&r==nowr)
{
lz[i]=x;
tree[i]=1ll*x*len[i];
}
else
{
push_down(i);
int mid=(nowl+nowr)/2;
if (r<=mid) setval(l,r,x,nowl,mid,lson);
else if (l>mid) setval(l,r,x,mid+1,r,rson);
else
{
setval(l,mid,x,nowl,mid,lson);
setval(mid+1,r,x,mid+1,nowr,rson);
}
push_up(i);
}
}

long long query(int l,int r,int nowl,int nowr,int i=1)
{
if (lz[i]) return 1ll*(r-l+1)*lz[i];
if (l==nowl&&r==nowr) return tree[i];
else
{
int mid=(nowl+nowr)/2;
if (r<=mid) return query(l,r,nowl,mid,lson);
else if (l>mid) return query(l,r,mid+1,nowr,rson);
else return query(l,mid,nowl,mid,lson)+query(mid+1,r,mid+1,nowr,rson);
}
}

int a[maxn];

int main()
{
int T;
scanf("%d",&T);
while (T--)
{
int n,q;
scanf("%d%d",&n,&q);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
long long sum=0;
for (int i=1;i<=n;i++) sum+=a[i];
int ma=-1,maj=-1;
for (int i=1;i<=n;i++) if (a[i]>ma) ma=a[i],maj=i;
int nowma=-1;
for (int i=1;i<=maj;i++)
{
nowma=max(nowma,a[i]);
val[i]=nowma;
}
nowma=-1;
for (int i=n;i>=maj;i--)
{
nowma=max(nowma,a[i]);
val[i]=nowma;
}
build(1,n);
while (q--)
{
char op[5];
scanf("%s",op);
if (op[0]=='P')
{
printf("%I64d\n",tree[1]-sum);
}
else
{
int id,h;
scanf("%d%d",&id,&h);
sum+=h;
a[id]+=h;
if (query(id,id,1,n)<a[id])
{
if (id==maj)
{
setval(id,id,a[id],1,n);
}
else if (id<maj)
{
if (a[id]<=a[maj]) setval(id,maj-1,a[id],1,n);
else
{
setval(id+1,maj,a[maj],1,n);
setval(id,id,a[id],1,n);
maj=id;
}
}
else
{
if (a[id]<=a[maj]) setval(maj+1,id,a[id],1,n);
else
{
setval(maj,id-1,a[maj],1,n);
setval(id,id,a[id],1,n);
maj=id;
}
}
}
}
}
}
return 0;
}

posted @ 2017-10-23 18:33  ACMsong  阅读(422)  评论(0编辑  收藏  举报