#线段树#UOJ 164【清华集训2015】V
分析
可以发现,三种操作均能被表示为 \(w=max(w+a,b)\) 的形式,
其中 \((a,b)=(x,-inf),(-x,0),(-inf,x)\),既然要求历史最大值,
那么就要同时维护当前以及历史的四个懒标记(\(a\) 和 \(b\)),主要是转移比较麻烦。
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
typedef long long lll; const lll inf=1e18;
const int N=500011; lll a[N]; int n,m;
int iut(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void print(lll ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
struct Segment_Tree{
lll mx[N<<2][2],lazy1[N<<2][2],lazy2[N<<2][2];
lll Plus(lll x,lll y){
if (x==-inf||y==-inf) return -inf;
return x+y;
}
void Clear_Lazy(int k){
lazy1[k][0]=0;
lazy1[k][1]=lazy2[k][0]=lazy2[k][1]=-inf;
}
void pup(int k){
mx[k][0]=max(mx[k<<1][0],mx[k<<1|1][0]);
mx[k][1]=max(mx[k<<1][1],mx[k<<1|1][1]);
}
void ptag(int k,lll z,lll Z,lll w,lll W){
mx[k][1]=max(mx[k][1],max(Plus(mx[k][0],Z),W));
lazy1[k][1]=max(lazy1[k][1],Plus(lazy1[k][0],Z));
lazy2[k][1]=max(lazy2[k][1],max(Plus(lazy2[k][0],Z),W));
mx[k][0]=max(Plus(mx[k][0],z),w);
lazy1[k][0]=Plus(lazy1[k][0],z);
lazy2[k][0]=max(Plus(lazy2[k][0],z),w);
}
void pdown(int k){
if (lazy1[k][0]==0&&lazy1[k][1]==-inf&&lazy2[k][0]==-inf&&lazy2[k][1]==-inf) return;
ptag(k<<1,lazy1[k][0],lazy1[k][1],lazy2[k][0],lazy2[k][1]);
ptag(k<<1|1,lazy1[k][0],lazy1[k][1],lazy2[k][0],lazy2[k][1]);
Clear_Lazy(k);
}
void build(int k,int l,int r){
Clear_Lazy(k);
if (l==r){
mx[k][0]=mx[k][1]=a[l];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pup(k);
}
void update(int k,int l,int r,int x,int y,lll z,lll w){
if (l==x&&r==y){
ptag(k,z,z,w,w);
return;
}
int mid=(l+r)>>1;
pdown(k);
if (y<=mid) update(k<<1,l,mid,x,y,z,w);
else if (x>mid) update(k<<1|1,mid+1,r,x,y,z,w);
else update(k<<1,l,mid,x,mid,z,w),update(k<<1|1,mid+1,r,mid+1,y,z,w);
pup(k);
}
lll query(int k,int l,int r,int x,int y,int t){
if (l==x&&r==y) return mx[k][t];
int mid=(l+r)>>1;
pdown(k);
if (y<=mid) return query(k<<1,l,mid,x,y,t);
else if (x>mid) return query(k<<1|1,mid+1,r,x,y,t);
else return max(query(k<<1,l,mid,x,mid,t),query(k<<1|1,mid+1,r,mid+1,y,t));
}
}Tre;
int main(){
n=iut(),m=iut();
for (int i=1;i<=n;++i) a[i]=iut();
Tre.build(1,1,n);
for (int i=1;i<=m;++i){
int opt=iut(),l=iut();
if (opt<4){
int r=iut(),z=iut();
if (opt==1) Tre.update(1,1,n,l,r,z,-inf);
else if (opt==2) Tre.update(1,1,n,l,r,-z,0);
else Tre.update(1,1,n,l,r,-inf,z);
}else print(Tre.query(1,1,n,l,l,opt-4)),putchar(10);
}
return 0;
}

浙公网安备 33010602011771号