BZOJ3600 沒有人的算術(替罪羊樹,線段樹)

2022-05-11 14:00:36 字數 1735 閱讀 4314

好神奇的資料結構題!l !1

題目大概意思是說你可以快速判斷兩個元素的大小,並且滿足偏序關係。

單點修改,求區間最大值。

題目用二元組滿足偏序關係確實巧妙。

因為滿足偏序關係,所以我們可以給它們對應乙個具體的數字,這樣比較時直接比較這個數字就行了。

但是我們需要支援動態標號,如果採用乙個排列來標號的話插入乙個數會有一大堆數字的變化發生變化。

我們考慮用實數來實現,整個值域從 [1,1e9] 開始,維護乙個 bst,插入時自己的值就取可選值域的一半。

但事實上如果 bst 深度很大的話也會被卡滿的!!1

我們需要乙個保證深度較小的平衡樹,而且不要有複雜的操作,發現替罪羊樹支援我們所有的操作,暴力重構在這題中變得十分優美。

另外序列上的問題我們需要維護一棵線段樹,線段樹要注意的是暴力重構時不必重新修改線段樹上涉及的所有節點,注意到偏序關係不會變,如果線段樹上記錄較大值是哪個節點而不是具體值即可。

**:

const int n = 100059;

const int m = 500909;

int v[m], cnt;

struct node

bool operator < (const node &i) const

bool operator == (const node &i) const

}val[m];

#define ls p << 1

#define rs ls | 1

int id[n], mx[n<<2], rt, m, n;

void build(int p, int l, int r)

inline bool cmp(int x, int y)

void change(int p, int l, int r, int x)

int query(int p, int l, int r, int l, int r)

return res;

}namespace sct

int build(int l, int r, int l, int r)

void rebuild(int &p, int l, int r)

int insert(int &p, int l, int r, node t)

int mid = (l + r) >> 1, res = 0;

if (t == val[p]) return p;

if (t < val[p]) res = insert(ls[p], l, mid - 1, t);

else res = insert(rs[p], mid + 1, r, t);

siz[p] = siz[ls[p]] + siz[rs[p]] + 1;

if (max(siz[ls[p]], siz[rs[p]]) >= siz[p] * 0.73) rebuild(p, l, r);

return res; }}

char op[5];

int main() else write(query(1, 1, n, l, r));

} return 0;}/*

5 10

c 1 1 1

c 2 1 2

q 1 2

c 4 4 4

c 5 5 5

q 4 5

q 3 3

c 4 2 3

c 4 4 4

q 3 4

*/

bzoj3600 沒有人的算術

time limit 20 sec memory limit 128 mb submit 1118 solved 452 submit status discuss 湖北省隊互測 week1 submit status discuss 神。神題。具體過程太抽象了。我們考慮如果能有一種方法能快速得到排...

bzoj 3600 沒有人的算術 替罪羊樹

為什麼我沒有copy題面呢?看到題面你就懂了.hh 題意 定義乙個二元組 二元組的兩個元素可以是二元組 如 x,y 其中x可以是 a,b,c 之類的 定義二元組的比較方式 先比較左邊,左邊相同再比較右邊。遞迴比較可以用隨便哪顆平衡樹維護,70分 考慮對於每個 二元組,對他定義乙個實數的對映來表示它的...

3600 沒有人的算術

time limit 20 sec memory limit 128 mb submit 616 solved 280 submit status discuss 湖北省隊互測 week1 submit status discuss 可以發現,每時每刻新增的元素加入之前元素組成的集合中,新集合內的元...