坑爹題面:
正常題面:
對於乙個序列支援下列5個操作:
1.區間加x
2.區間減x並與0取max
3.區間覆蓋
4.單點查詢
5.單點歷史最大值查詢
題解:每個區間維護乙個標記函式f(x)=max(x+a,b)
那麼兩個標記 f 和 g 的合併就是g(f(x))=max(x+max(fa+ga,-inf),max(fb+ga,gb))(打f標記的時間在前,打g標記在後)
區間加減就是打上max(x,0),區間覆蓋就是打上max(-inf,x)
只要記錄歷史最大標記即可維護歷史最大值
code:
1 #include2 #include3 #include4 #include5 #include6using
namespace
std;
7 typedef long
long
int64;
8char
ch;9
bool
ok;10
void read(int &x)
15const
int maxn=500005;16
const int64 inf=4557430888798830399ll;
17int
n,m,val[maxn],op,l,r,x;
18 typedef pairpii;
19#define a first
20#define b second
21 pii operator+(const pii &x,const pii &y)
22 pii max(const pii &x,const pii &y)
23struct
seg29
int m=(l+r)>>1
;30 build(ls,l,m),build(rs,m+1
,r);31}
32void pushdown(int
k)38
void modify(int k,int l,int r,int x,int
y,pii v)
40int m=(l+r)>>1
; pushdown(k);
41if (y<=m) modify(ls,l,m,x,y,v);
42else
if (x<=m) modify(ls,l,m,x,m,v),modify(rs,m+1,r,m+1
,y,v);
43else modify(rs,m+1
,r,x,y,v);44}
45void add(int x,int y,int v)
46void cov(int x,int y,int v)
47 int64 query(int k,int l,int r,int x,int
op)52
int m=(l+r)>>1
; pushdown(k);
53if (x<=m) return query(ls,l,m,x,op); else
return query(rs,m+1
,r,x,op);54}
55 int64 query(int x,int op)
56}t;
57int
main()
69return0;
70 }
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 要查詢單點值的話只要把所...