題解 UOJ 164 清華集訓2015 V

2022-05-15 13:57:37 字數 2421 閱讀 4399

這道題題目簡潔新穎,吸引讀者閱讀興趣...

目錄正解

注:更完整的版本在這裡。

點這裡

需要你維護長度為n的序列並支援下列操作:

區間加法;

區間賦值;

區間每個 \(a_i\) 變成 \(\max⁡(a_i-t,0)\);

單點詢問值

單點詢問歷史最大值

\(n,m≤500000\),其中 \(m\) 為運算元。

首先考慮,如果這道題沒有歷史版本我們該怎麼做?

其實很簡單,這裡我就不贅述了 其實是我懶得說 。

那麼我們考慮,對於這個 \(5\) 操作,我們應該怎麼做?

首先,分析 \(3\) 操作,這是乙個很特殊的操作。

對於每個 \(a_i\) ,將 \(a_i\) 修改為 \(\max(a_i-t,0)\),我們把它寫成函式,即

\[f(x)=\max(x-t,0)

\]寫成一般形式,即

\[f(x)=\max(x+a,b)

\]那麼,我們可以輕鬆地畫出這個函式的影象:

考慮能否將兩個函式 \(f_1(x),f_2(x)\) 的最大值全部合併,成為 \(g(x)\),即如下圖

顯然是可行的,具體如何實現請自行思考,如果實在不行,看看**也好啊。

現在,我們來看這樣的函式能不能疊加,即對於 \(f(x)=\max(x+a,b)\),能不能給 \(a+\delta\) 或者 \(b+\delta\)。

顯然這也是可行的,即新的 \(f'(x)=\max(x+a+\delta,b)\) 或者是 \(f'(x)=\max(x+a,b+\delta)\)。

發現這個函式有疊加性以及能夠維護函式最大,發現似乎可以用這樣的函式來做這道題,但是,需要對我們的操作進行一些變換:

設標記 \((a,b)\) 表示將 \(x\) 變成 \(\max⁡(a+x,b)\) 。

假設對乙個位置作用的標記對應函式依次為 \(f_1 (x),f_2 (x)\ldots,f_k (x)\)

歷史最大值對應函式為 \(\max\(……f_1(x)))\}\)

如若能維護出該函式,歷史最大值即可維護出。

可以發現將兩個這樣函式取 \(\max\) 後仍然是乙個形式一樣的函式(見上面的圖)。於是歷史最大值的函式即可維護。用線段樹在每個區間維護當前標記的函式和歷史最大值的函式即可,這兩個都支援 \(\mathcal o(1)\) 合併。於是複雜度為 \(\mathcal o(n\log⁡n)\)。

#include #include #include #include #include using namespace std;

// #define ndebug

#include namespace elaina

templateinline void getmin(t& x, const t rhs)

templateinline void getmax(t& x, const t rhs)

templateinline t readin(t x)

}using namespace elaina;

const int maxn=5e5;

const ll inf=1ll<<50;

ll x[maxn+5];

int n, m;

namespace saya;

}inline func operator ^(const func& rhs) const;

}inline ll operator ()(const ll& x) const

};func tag[maxn<<2|2], histag[maxn<<2|2];

#define ls (i<<1)

#define rs (i<<1|1)

#define mid ((l+r)>>1)

#define fa (i>>1)

#define _lhs ls, l, mid

#define _rhs rs, mid+1, r

#define _this i, l, r

inline void update(int i)

inline void pushdown(int i);

}void build(int i, int l, int r);

if(l==r) return;

build(_lhs), build(_rhs);

}void modify(int l, int r, func f, int i, int l, int r)

pushdown(i);

if(l<=mid) modify(l, r, f, _lhs);

if(mid

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 要查詢單點值的話只要把所...