線段樹相關

2022-10-10 15:57:10 字數 2341 閱讀 3832

大意:給定\(n\)個旅館,初始全為空。有兩種詢問方式。

1.輸入\(x\),查詢滿足連續空旅館數\(\ge x\)的最小編號,並在此\(x\)間開房。

2.輸入\(l,r\), 給指定區間退房。

對線段樹的節點維護以下資訊:

修改一段區間時,由於線段樹的性質,會將區間分解為若干結點所代表的區間,在覆蓋或清空時,可直接將\(lz\)設為\(1/2\),同時將\(lnum,rnum.num\)設為\(0/len\)。具體合併下傳等操作見**。

實現時有一些細節注意一下,要想清楚線段樹各項操作的過程,注意當\(n=1\)和對葉子節點的處理。寫這類資料結構題找不出bug可以暴力對拍,多在板子中加一些輸出函式和\(assert\)之類的查錯。

#include "bits/stdc++.h"

using namespace std;

class segtree

else if(v == 2)

else }};

node unite(const node& a, const node& b) const

else

if(a.lnum == a.len)

else

res.num = max(max(res.lnum, res.rnum), a.rnum + b.lnum);

res.num = max(res.num, max(a.num, b.num));

return res;

}inline void push(int x, int l, int r)

}inline void pull(int x, int z)

int n;

vectortree;

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

int y = (l + r) >> 1;

int z = x + ((y - l + 1) << 1);

build(x + 1, l, y);

build(z, y + 1, r);

pull(x, z);

}int get(int x, int l, int r, int p)

int y = (l + r) >> 1;

int z = x + ((y - l + 1) << 1);

push(x, l, r);

if(tree[x + 1].num >= p)

else if(tree[x + 1].rnum + tree[z].lnum >= p)

else if(tree[z].num >= p)

pull(x, z);

return res;

}template void modify(int x, int l, int r, int ll, int rr, const m&... v)

int y = (l + r) >> 1;

int z = x + ((y - l + 1) << 1);

push(x, l, r);

if (ll <= y)

if (rr > y)

pull(x, z);

}segtree(int _n) : n(_n)

int get(int p)

template void modify(int ll, int rr, const m&... v)

};void solve()

else

}else

}}

似乎維護最大子段和一類的都是這個套路,某最大的某連續區間滿足...要麼在左區間,要麼在右區間,要麼就在兩區間合併處。

大意: 乙個兔子在一顆完全二叉樹上移動,每次移動可以移動到兩個兒子節點或父親節點,給定一串移動序列,每次詢問給定起點,問從起點經過\(l-r\)這段移動,終點的位置。需要支援單點修改

一條路徑可以用乙個二進位制數來表示,從左到右,若是1就向右兒子移動,0則向左兒子移動。在路徑的二進位制表達中,不體現退格。對於一段\(l-r\)的操作,我們可以將其看作乙個整體,當執行這段操作序列時,需要先退格多少,再怎樣進行移動。可以發現若當前在s點,執行過後的終點為 \(((s >> backnum) << lenofpath) + path\)。注意到這個幾個資訊線段樹可以維護。

合併**

node unite(const node& a, const node& b) const 

else

return res;

}

修改是單點修改,所以不需要維護懶標記。

線段樹 02 構建線段樹

public inte ce merger 不能再縮小的基本問題是 對treeindex指向的節點的情況進行討論 public class segmenttree 在treeindex的位置建立表示區間 l.r 的線段樹 private void buildsegmenttree int treei...

線段樹 01 線段樹基礎

物理上 public class segmenttree public int getsize public e get int index 返回完全二叉樹的陣列表示中,乙個索引所表示的元素的左孩子節點的索引 private int leftchild int index 返回完全二叉樹的陣列表示中...

線段樹和zkw線段樹

好啦,我們就開始說說線段樹吧 線段樹是個支援區間操作和查詢的東東,平時的話還是蠻實用的 下面以最基本的區間加以及查詢區間和為例 線段樹顧名思義就是棵樹嘛,葉子節點是每個基本點,它們所對應的父親就是它們的和,具體如下圖 但是對於這樣的線段樹來說,操作所需的時間是遠達不到我們的要求的 會被t 因為我們會...