164 清華集訓2015 V

2021-08-05 23:27:09 字數 1518 閱讀 5563

一段序列,支援五個操作。

1、區間加

2、區間減,然後對0取max

3、區間賦值

4、單點查詢

5、單點查詢歷史最大值

前三個操作可以看成一種:給原數加a,再和b取max。即

1、x=max(x+a,0)

2、x=max(x-a,0)

3、x=max(x-inf,b)

發現標記max(x+a1,b1)和max(x+a2,b2)可以合併為max(x+a1+a2,max(b1+a2,b2))

然後只剩下第5種操作。

再給每個點維護乙個歷史最大值標記。合併後標記=max(x+max(a1,a2),max(b1,b2))。

注意標記必須打、pushdown的順序必須按**裡那樣來。不然會是錯的。

可以通過這樣一組小資料感性理解一下。

4 41 2 3 4

1 1 2 5

2 1 2 1

1 1 4 2

5 2注意這個**不加inline會t,加了inline跑得比o2還筷。

#include#include#include#includeusing namespace std;

#define rep(i,j,k) for(i=j;i<=k;++i)

#define per(i,j,k) for(i=j;i>=k;--i)

#define sqr(x) ((x)*(x))

#define g getchar()

#define ll long long

#define pll pair#define mkp make_pair

#define x first

#define y second

#define n 500005

#define nn 2000005

#define inf 1000000000000000ll

int n;ll a[n],la1[nn],lb1[nn],la2[nn],lb2[nn],a1[nn],b1[nn],a2[nn],b2[nn];

inline int read()

inline void add(ll a,ll b,int num)

inline void add2(ll a,ll b,int num)

inline void pd(int num)

void ins(int l,int r,ll a,ll b,int l,int r,int num)

int mid=l+r>>1;pd(num);

if(l<=mid)ins(l,r,a,b,l,mid,num<<1);

if(r>mid)ins(l,r,a,b,mid+1,r,num<<1|1);

}ll query1(int x,int l,int r,int num)

ll query2(int x,int l,int r,int num)

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

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