區間第K大(POJ 2104)

2021-10-02 02:39:50 字數 1238 閱讀 9938

可持久化線段樹不是一顆完全二叉樹,所以不能用層次序編號,而應該直接記錄每個節點的左、右子節點的編號。可持久化線段樹維護了每次操作後線段樹的歷史形態。

下面舉個簡單的例子來理解一下:

以poj-2104為例;這棵樹是一顆不用修改的線段樹

題意:即多次查詢,查詢區間第k大的數。

//主席樹的學習--區間第k大

//區間第k大又可以用整體分治演算法,歸併樹,線段樹套平衡樹,主席樹來做

//以主席樹為例來做

#include#includeusing namespace std;

const int maxn = 1e5 + 5;

struct segmenttreetree[maxn * 30];

int tot, root[maxn];//主席樹的總點數和每個根

int a[maxn], b[maxn];//a用來存原數列,b用來存離散之後的

int n, m;

int cnt;

int build_tree(int l, int r)

*/ if (l == r)

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

tree[step].lc = build_tree(l, mid);

tree[step].rc = build_tree(mid + 1, r);

tree[step].dat = tree[tree[step].lc].dat + tree[tree[step].rc].dat;

return step;

}int update(int rt, int pos, int val)

else

tree[step].dat = tree[rt].dat + val;

} return temp;

}int query(int r1, int r2, int k)

else

} return l;

}int main()

sort(b, b + n);

cnt = unique(b, b + n) - b;

tot = 0;

root[0] = build_tree(1, cnt);

for (int i = 1; i <= n; i++)

int l, r, k;

while (m--)

return 0;

}

poj2104 主席樹區間第k大

主席樹裸題,過了好久都快忘了。主席樹主要就是使多個線段樹並行於一顆樹中,儲存的是一段區間內數字出現的個數,所以先離散化。數字的更改只影響了一條從這個葉子節點到根的路徑,所以只有這條路徑是新的,其他的都沒有改變。比如對於某個節點,要往右邊走,那麼左邊那些就不用新建,只要用個指標鏈到原樹的此節點左邊就可...

poj 2104 主席樹 靜態區間第k大

主席樹入門題目,主席樹其實就是可持久化權值線段樹,rt i 維護了前i個數中第i大 小 的數出現次數的資訊,通過查詢兩棵樹的差即可得到第k大 小 元素。include include include using namespace std define lson i node i lson defi...

POJ 2104 區間第k大 主席樹(模板)

查詢區間範圍內,第 k kk 大的數 按照數列順序依次加入,構建可持久化線段樹 主席樹 由於線段樹的可減性,能夠得到對應區間範圍內的線段樹 主席樹的模板題了 int cnt,root maxn a maxn struct nodet maxn 40 vector int v intgetid int...