主席樹區間第K大

2022-05-20 13:18:36 字數 1611 閱讀 3549

主席樹的實質其實還是一顆線段樹, 然後每一次修改都通過上一次的線段樹,來新增新邊,使得每次改變就改變logn個節點,很多節點重複利用,達到節省空間的目的。

1.不帶修改的區間第k大。

hdu-2665 模板題

**:

1 #include2

using

namespace

std;

3#define fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);

4#define ll long long

5#define ull unsigned ll

6#define fi first

7#define se second

8#define pb push_back

9#define lson l,m,rt<<1

10#define rson m+1,r,rt<<1|1

11#define max3(a,b,c) max(a,max(b,c))

12#define min3(a,b,c) min(a,min(b,c))

13 typedef pairpll;

14const

int inf = 0x3f3f3f3f;15

const ll mod = 1e9+7;16

const

int n = 1e5+10;17

struct

nodetree[n*20

];21

int tot = 0;22

introot[n];

23int

rank[n];

24int

b[n];

25structn31

}a[n];

3233

int build(int l, int

r)42

int update(int pre, int l, int r, int

k)53

else tree[now].num = 1;54

return

now;55}

56int query(int u, int v, int l, int r,int

k)63

intmain()

73 sort(a+1, a+1+n); ///

離散化74

int t = 0

;75 a[0].a = -1;76

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

80 tot = 0

;81 root[0] = build(1

,t);

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

83 root[i] = update(root[i-1], 1

, t, b[i]);

84while(m--)89}

90return0;

91}92/*931

9410 1

951 4 2 3 5 6 7 8 9 0

961 3 2

9798

*/

區間第k大(主席樹)

學了一下主席樹模板題,當初看了網上的主席樹講解都沒有看懂,後面看了嗶哩嗶哩的uestc的主席樹,終於看懂了思想。每次更新的複雜度都為logn。每次更新的話就是對要更新的點路徑上的點重新更加乙個,然後進行對沒有影響的那些進行連邊。然後用乙個root記錄每乙個線段樹的根節點下標。include incl...

主席樹求區間第k大

主席樹是可持久化線段樹,維護 權值個數 線段樹的字首和。相當於對每個區間 1,i 建立n顆線段樹。我們用乙個區間內的數的出現個數建線段樹,所以資料大小較大時一般進行離散化。建的是權值線段樹,即用數值作為區間,每個節點存該數出現的次數,所以query返回的其實是離散後的陣列b的下標idx,最終結果為b...

區間第k大的數 主席樹

套主席樹求區間第k小的數的模板,然後求區間 l,r 第k大的數就等於求區間 l,r 第r l 1 k小的數 下標從1開始 區間第k小值問題 有n個數,多次詢問乙個區間 l,r 中第k小的值是多少。查詢區間 l,r 中的第k小值 我們按照從1到n的順序依次將資料插入可持久化的線段樹中,將會得到n 1個...