UOJ 164 清華集訓2015 V

2022-05-21 12:36:17 字數 1224 閱讀 2623

這道題由於是單點詢問,所以異常好寫。

注意到每種修改操作都可以用乙個標記\((a,b)\)表示。標記\((a,b)\)的意義就是\(x= \max\\) 

同時這種標記也是支援合併的。有\((a,b)+(c,d)=(a+c,\max\)\)

用上這種標記的話,\(1\)操作就是\((x,0)\),\(2\)操作就是\((-x,0)\),\(3\)操作就是\((-inf,x)\)。

要查詢單點值的話只要把所有標記都下放了就好了。

這種標記也支援取\(\max\)。即,\(\max\=(\max\,\max\)\)。本質上就是乙個分段函式取\(\max\)的過程。

所以最後一問再維護乙個歷史最大值這道題就做完了。注意下傳標記時先傳歷史標記。

還有乙個要注意的地方:標記\((a,b)\)裡的\(a\)實際上是\(\max\\)。注意修改的時候和\(-inf\)取個\(max\),不然很容易就爆掉了。

下面貼**:

#include#include#include#include#include#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)

#define max(a,b) (a>b?a:b)

#define maxn 500010

#define inf (1ll<<60)

using namespace std;

typedef long long llg;

int n,m,l,r;

llg na[maxn<<2],nb[maxn<<2];

llg pa[maxn<<2],pb[maxn<<2],za,zb;

int getint()

void pushdown(int u)

na[u]=nb[u]=pa[u]=pb[u]=0;

}void build(int u,int l,int r)

void add(int u,int l,int r)

pushdown(u);

if(l<=mid) add(lc,l,mid);

if(r>mid) add(lv,mid+1,r);

}void query(bool w)

za=w?na[u]:pa[u];

zb=w?nb[u]:pb[u];

}int main()

else

} return 0;

}

uoj164 清華集訓2015 V

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

UOJ 164 清華集訓2015V

qwqzcysky真是菜死了,這是我剛上高一的時候坤爺在夏令營講的,可是今天才切掉 想想也神奇,乙個2016.11才學會線段樹的菜雞,夏令營的時候居然聽過segment tree beats?所以我們來看下這個神奇的segment tree beats.我們維護乙個神奇的標記二元組 x,y 在樹點上...

UOJ 164 清華集訓2015 V

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