【UOJ#164】清华集训2015V
QwQzcysky真是菜死了,这是我刚上高一的时候坤爷在夏令营讲的,可是今天才切掉……
想想也神奇,一个2016.11才学会线段树的菜鸡,夏令营的时候居然听过Segment-Tree-Beats?
所以我们来看下这个神奇的Segment-Tree-Beats.
我们维护一个神奇的标记二元组(x,y),在树点上打这个标记表示$val[o]=max(val[o]+x,y)$
然后我们看一下它是不是可以合并(否则这就是一个没有的东西)
merge:merge(Tag[x],Tag[y])=(x1+x2,max(y1+x2,y2))
那么我们怎么把操作对应到标记修改上呢?
- opt1:(x,0)
- opt2:(-x,0)
- opt3:(-inf,x)
query的时候查询标记,正常pushdown就行了。
所以再维护一下历史最大值,这个对于做过一些简单的Segment-Tree-Beats的同学来说简直是简单的不行。
不过每次修改的时候有一个小细节,(x,y)的x最好是max(x,-inf),否则会出事。
#include<bits/stdc++.h> #define N 500010 #define lson (o<<1) #define rson (o<<1|1) using namespace std; typedef long long ll; const ll inf=1e18; int n,m; struct Tag{ ll x,y,tx,ty; Tag(ll x=0,ll y=0,ll tx=0,ll ty=0):x(x),y(y),tx(tx),ty(ty){} }; ll a[N]; struct Segment_Tree_Beats{ ll val[N<<2];Tag tag[N<<2]; inline Tag merge(Tag a,Tag b){ return Tag(max(a.x+b.x,-inf),max(a.y+b.x,b.y),max(a.tx,a.x+b.tx),max(a.ty,max(a.y+b.tx,b.ty))); } inline void pushdown(int o,int l,int r){ if(l==r)return; tag[lson]=merge(tag[lson],tag[o]); tag[rson]=merge(tag[rson],tag[o]); tag[o]=Tag(0,0,0,0); } void build(int o,int l,int r){ tag[o]=Tag(0,0,0,0); if(l==r)return;int mid=(l+r)>>1; build(lson,l,mid);build(rson,mid+1,r); } void change(int o,int l,int r,int ql,int qr,Tag v){ if(ql<=l&&r<=qr){tag[o]=merge(tag[o],v);return;} int mid=(l+r)>>1;pushdown(o,l,r); if(ql<=mid)change(lson,l,mid,ql,qr,v); if(qr>mid)change(rson,mid+1,r,ql,qr,v); } Tag query(int o,int l,int r,int q){ if(l==r)return tag[o]; int mid=(l+r)>>1;pushdown(o,l,r); if(q<=mid)return query(lson,l,mid,q); else return query(rson,mid+1,r,q); } }T; inline int read(){ int f=1,x=0;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } int main(){ n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); T.build(1,1,n); while(m--){ Tag ans;int opt=read(); if(opt==1){ int l=read(),r=read(),x=read(); T.change(1,1,n,l,r,Tag(x,-inf,x,-inf)); } if(opt==2){ int l=read(),r=read(),x=read(); T.change(1,1,n,l,r,Tag(-x,0,-x,0)); } if(opt==3){ int l=read(),r=read(),x=read(); T.change(1,1,n,l,r,Tag(-inf,x,-inf,x)); } if(opt==4){ int x=read();ans=T.query(1,1,n,x); printf("%lld\n",max(a[x]+ans.x,ans.y)); } if(opt==5){ int x=read();ans=T.query(1,1,n,x); printf("%lld\n",max(a[x]+ans.tx,ans.ty)); } } }
zzq wc-ctsc-apio-NOI Au;yql精通多项式;zyz精通女装;由乃精通数据结构;孔老师是毒奶大师;我没有学上:我们都有光明的前途。