首先發現三種操作可以轉化為同樣的形式,定義(x,
y)
(x,y)
(x,y
)為區間加上x
xx後與y
yy取max的標記,那麼區間加就是(x,
0)
(x, 0)
(x,0
),區間減就是(−x
,0
)(-x, 0)
(−x,0)
,區間賦值就是(−i
nf,x
)(-inf,x)
(−inf,
x),這個標記合併也比較方便,在(a,
b)
(a,b)
(a,b
)標記後加上(c,
d)
(c,d)
(c,d
)這個標記就變成了(a+
c,ma
x(b+
c,d)
)(a+c,max(b+c,d))
(a+c,m
ax(b
+c,d
))。這樣子我們就能很方便實現單點查詢了,但是單點歷史最大值查詢似乎不太好做,我們對於每個點維護乙個歷史最大值標記,分別表示作用在這上面的所有標記中的兩維分別的歷史最大值,意思就是兩維並不需要在同乙個時候打上這個標記,下放的時候把父親的歷史最大值標記直接給兒子就好了,因為在下放前的所有影響了父親的標記一定會影響兒子,並且這些標記是在兒子標記確定好之後發生的,所以可以直接把歷史最大值標記合併到兒子的當前標記上,複雜度o
(n log n
)o(\text)
o(n log n)。
#include
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define inf (0x3f3f3f3f)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a) for (int i = 0; i < a; ++ i)
#define for(i, a, b) for (int i = a; i <= b; ++ i)
#define for(i, a, b) for (int i = a; i >= b; -- i)
using
namespace std;
typedef
long
long ll;
typedef pair pll;
template
<
class
t>
inline t read
(t &_)
template
<
class
t>
inline
bool
chkmax
(t &_, t __)
template
<
class
t>
inline
bool
chkmin
(t &_, t __)
inline
void
prostatus()
const ll inf =
1e18
;const
int n =
5e5+7;
inline pll max
(pll x, pll y)
inline pll merge
(pll x, pll y)
inline
void
chkmax
(pll &x, pll y)
struct segment_tree
void
pushdown
(int bh)
now[bh]
= his[bh]=mp
(0, tag[bh]=0
);}void
update
(int bh,
int l,
int r,
int x,
int y, pll z)
else
}int
query
(int bh,
int l,
int r,
int x)
}t;int
main()
else
}return0;
}
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 要查詢單點值的話只要把所...