UOJ 164 清華集訓2015V

2022-03-03 09:37:25 字數 1498 閱讀 7605

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))

那麼我們怎麼把操作對應到標記修改上呢?

query的時候查詢標記,正常pushdown就行了。

所以再維護一下歷史最大值,這個對於做過一些簡單的segment-tree-beats的同學來說簡直是簡單的不行。

不過每次修改的時候有乙個小細節,(x,y)的x最好是max(x,-inf),否則會出事。

#include#define n 500010

#define lson (o<<1)

#define rson (o<<1|1)

using

namespace

std;

typedef

long

long

ll;const ll inf=1e18;

intn,m;

struct

tag};

ll a[n];

struct

segment_tree_beats

inline

void pushdown(int o,int l,int

r)

void build(int o,int l,int

r)

void change(int o,int l,int r,int ql,int

qr,tag v)

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)}t;

inline

intread()while(ch<'

0'||ch>'9'

);

dowhile(ch>='

0'&&ch<='9'

);

return f*x;

}int

main()

if(opt==2

)

if(opt==3

)

if(opt==4

)

if(opt==5

) }

}

uoj164 清華集訓2015 V

題目鏈結 164.清華集訓2015 v 大佬的部落格 jefflyy 這個東西,詭異的標記下傳。一共有五種操作,區間加法,區間減法 減到0就不減了 區間覆蓋,單點詢問,單點歷史最大值。非常巧妙的使用了乙個pair來進行標記。y max x a,b 就是可以看做建立乙個直角座標系,其中x軸表示原數字,...

UOJ 164 清華集訓2015 V

這道題由於是單點詢問,所以異常好寫。注意到每種修改操作都可以用乙個標記 a,b 表示。標記 a,b 的意義就是 x max 同時這種標記也是支援合併的。有 a,b c,d a c,max 用上這種標記的話,1 操作就是 x,0 2 操作就是 x,0 3 操作就是 inf,x 要查詢單點值的話只要把所...

UOJ 164 清華集訓2015 V

164.清華集訓2015 v 貌似是乙個 題,是jls線段樹的題目。首先我們定義一種標記 a,b 表示給這個區間先加上 a 再跟 b 取 max 不難發現題目裡提到的三種操作分別都可以用這樣的標記來代替 1 區間加 v v,inf 2 區間減 v v,0 3 區間覆蓋 inf,v 考慮合併兩個標記 ...