可持久化線段樹初步

2022-06-05 02:51:08 字數 3371 閱讀 9601

可持久化線段樹是可以查詢歷史版本的資料結構,比如說查詢區間第k大的數,那麼我們需要查詢到1-r 和 1- (l - 1) 資料的分布情況,以完成查詢。

2023年11月25日

模板題 poj2104

1 #include 2 #include 3 #include 4

#define rep(i, a, b) for (int i = a; i <= b; i++)

5#define rep(i, a, b) for (int i = a; i < b; i++)

6#define drep(i, a, b) for (int i = a; i >= b; i--)

7#define mp make_pair

8#define pb push_back

9#define clr(x) memset(x, 0, sizeof(x))

10#define xx first

11#define yy second

12using

namespace

std;

13 typedef long

long

i64;

14 typedef pairpii;

15const

int inf = ~0u>>1;16

const i64 inf = ~0ull >> 1;17

//*********************************

1819

const

int maxn = 100005, maxm = 2060965;20

intsum[maxm];

21int

lson[maxm], rson[maxm];

2223

intread()

27while (ch >= '

0' && ch <= '

9')

28return l *s;29}

3031

inttotnode;

32void build(int x, int &y, int l, int r, int

v) 40

else44}

4546

int query(int x, int y, int l, int r, int

k) 52

53int

val[maxn], hsh[maxn], root[maxn];

54int

main()

6970

return0;

71 }

view code

樹上第k大 清橙1501 樹

以每一條鏈建立線段樹,然後用第乙個點減去lca加上第二個點減去lca上面那個點的值來查詢,注意,線段樹里開的是每個區間有多少個數。

1 #include 2

#define rep(i, a, b) for (int i = a; i <= b; i++)

3#define rep(i, a, b) for (int i = a; i < b; i++)

4#define drep(i, a, b) for (int i = a; i >= b; i--)

5#define pb push_back

6#define mp make_pair

7#define xx first

8#define yy second

9using

namespace

std;

10 typedef long

long

i64;

11 typedef pairpii;

12const

int inf = ~0u >> 1;13

const i64 inf = ~0ull >> 1;14

//*****************************

15const

int maxn = 200005, maxm = 1700005;16

struct

ed 18 ed(int _u, int _v, int

_nx) :

19u(_u), v(_v), nx(_nx) {}

20 } e[maxn << 1

];21

intg[maxn], ccnt;

22void addedge(int u, int

v) 26

int dep[maxn], fa[maxn][18

];27

bool

vis[maxn];

28int

val[maxn];

29void build_lca(int

x) 35

for (int i = g[x]; i != -1; i = e[i].nx) if (!vis[e[i].v]) 40}

41int ask(int l, int

r) 48}49

if (l == r) return

l;50 drep(i, 17, 0

) 54}55

return fa[l][0

];56}57

intsum[maxm], lson[maxm], rson[maxm], ndtot, root[maxm];

58void build(int x, int &y, int l, int r, int

v) 66

else70}

71int

cnt;

72void dfs(int x, int

father)

77int query(int x1, int y1, int x2, int y2, int l, int r, int

k) 83

int solve(int x, int y, int lca, int

op)

90return query(root[x], root[st1], root[y], root[st2], 1

, cnt, k);91}

92int

read()

96while (ch >= '

0' && ch <= '

9')

97return l *s;98}

99int

hsh[maxn];

100int

main()

111 build_lca(1

);112 cnt =cd;

113 dfs(1, 0

);114 rep(i, 1

, m)

120return0;

121 }

view code

線段樹初步 可持久化線段樹

人的知識就好比乙個圓圈,圓圈裡面是已知的,圓圈外面是未知的。你知道得越多,圓圈也就越大,你不知道的也就越多。芝諾 線段樹以其特點能被用來解決許多的問題,其拓展性極強。故學好 用好線段樹對增加你的 長度有顯著作用。這篇簡小的文章,就來講一講線段樹的一種變式 可持久化線段樹 又作主席樹 函式式線段樹等 ...

可持久化線段樹總結(可持久化線段樹,線段樹)

最近正在學習一種資料結構 可持久化線段樹。看了網上的許多部落格,弄了幾道模板題,思路有點亂了,所以還是來總結整理下吧。你需要維護這樣的乙個長度為 n 的陣列,支援如下幾種操作 在某個歷史版本上修改某乙個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每進行一次操作 對於操作2,即為生成乙個完全一...

可持久化線段樹

可持久化線段樹,意思是可以查詢歷史記錄的線段樹。又叫主席樹。我們可以通過記錄不同的根節點,並在每乙個更新到的節點處新建必要的節點。詢問不同版本的主席樹,只需要進入不同的根節點即可。例題 給定n,m,輸入n個數組成的數列,有m個詢問,每次詢問l,r這個區間中,第k小的數的值。分析 這個題可以巧妙運用主...