題目鏈結:#164. 【清華集訓2015】v
大佬的部落格:jefflyy
這個東西,,,詭異的標記下傳。
一共有五種操作,區間加法,區間減法(減到0就不減了),區間覆蓋,單點詢問,單點歷史最大值。
非常巧妙的使用了乙個pair來進行標記。y=max(x+a,b)。
就是可以看做建立乙個直角座標系,其中x軸表示原數字,y軸表示修改後的數字,那麼加法可以看做是y=m
ax(x
+a,0
)y=max(x+a,0)
y=max(
x+a,
0),減法可以看做為y=m
ax(x
−a,0
)y=max(x-a,0)
y=max(
x−a,
0),覆蓋則為y=a
或者y=
max(
−oo,
a)
y=a或者y=max(-oo,a)
y=a或者y
=max
(−oo
,a),故可以將這三種標記統一成(x+
a,b)
(x+a,b)
(x+a,b
)的形式。
那麼假設原來的標記是(a1
,b1)
(a_1,b_1)
(a1,b
1),這是來了乙個(a2
,b2)
(a_2,b_2)
(a2,b
2)的標記,那麼可以合併為:(a1
+a2,
max(
b1+a
2,b2
))
(a_1+a_2,max(b_1+a_2,b_2))
(a1+a
2,m
ax(b
1+a
2,b
2))
。那麼單點詢問就是max
(x+a
,b
)max(x+a,b)
max(x+
a,b)
了。歷史最大值的話,我們只需要記錄歷史**現過的最大標記即可。
#include
using namespace std;
typedef
long
long ll;
const
int maxn=
5e5+7;
const ll inf=
1e18
;int a[maxn<<2|
1];pair p[maxn<<2|
1];//max(x+a,x=b);
pair maxx[maxn<<2|
1];void
build
(int l,
int r,
int k)
int mid=
(l+r)
>>1;
build
(l,mid,k<<1)
;build
(mid+
1,r,k<<1|
1);}
void
pushdown
(int l,
int r,
int k)
}void
updata
(int l,
int r,
int k,
int l,
int r,ll a,ll b)
pushdown
(l,r,k)
;int mid=
(l+r)
>>1;
if(l<=mid)
updata
(l,mid,k<<
1,l,r,a,b);if
(r>mid)
updata
(mid+
1,r,k<<1|
1,l,r,a,b);}
ll myfindid
(int l,
int r,
int k,
int id)
ll myfindmax
(int l,
int r,
int k,
int id)
intmain()
else
if(id==2)
else
if(id==3)
else
if(id==4)
else
}return0;
}
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 要查詢單點值的話只要把所...
UOJ 164 清華集訓2015 V
164.清華集訓2015 v 貌似是乙個 題,是jls線段樹的題目。首先我們定義一種標記 a,b 表示給這個區間先加上 a 再跟 b 取 max 不難發現題目裡提到的三種操作分別都可以用這樣的標記來代替 1 區間加 v v,inf 2 區間減 v v,0 3 區間覆蓋 inf,v 考慮合併兩個標記 ...