主席樹學習記錄

2021-06-29 05:19:52 字數 2851 閱讀 5400

搞了一段時間網路流後,最後還是回到了資料結構。。。

主席樹,引fotile主席的一段話:

..這個東西是當初我弱不會劃分樹的時候寫出來替代的乙個玩意..被****有用心的人取了很奇怪的名字》 <

想法是對原序列的每乙個字首[1..i]建立出一顆線段樹維護值域上每個數的出現次數,然後發現這樣的樹是可以減的,然後就沒有然後了

其實是一種比較好理解的資料結構(至少靜態查詢時是如此),我們對於每個點,建乙個類似與字首和的線段樹,然後我們發現這樣的n棵線段樹是可以相減的,於是。。。但是在實現過程中,由於記憶體限制的原因,我們一般用指標實現。

cogs 930 找第k小的數。裸題,直接上模板。code:

#include#include#include#include#define mid (l+r)/2

using namespace std;

struct node

int updata()

}*null=new node(),*root[100001]=,q[2000001];

int n,m,a[100001],b[100001];

int temp,ans;

void build(node *&y,node *&x,int l,int r,int t)

if (t<=b[mid])

else

}void find(node *x1,node *x2,int l,int r,int k)

if (x2->left) ls+=x2->left->size;

if (x1->left) ls-=x1->left->size;

if (ls>=k) find(x1->left,x2->left,l,mid,k);

else find(x1->right,x2->right,mid+1,r,k-ls);

}int main()

sort(b+1,b+n+1);

size=unique(b+1,b+n+1)-b-1;

temp=0;

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

build(root[i],root[i-1],1,size,a[i]);

for (i=1;i<=m;++i)

fclose(stdin);

fclose(stdout);

}

動態主席樹,其實救是樹狀陣列套線段樹,cogs 257 動態排名系統 code:

#include#include#include#include#define mid (l+r)/2

using namespace std;

struct hptree[10000001];

struct hqqst[10001];

int t,n,m,tot,size;

int root[50001],a[50001],b[60001],q1[2000],q2[2000];

int lowbit(int x)

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

void insert(int last,int &i,int l,int r,int x,int flag)

void bit_ins(int i,int x,int flag)

int ask(int l,int r,int k)

else

}int bit_ask(int l,int r,int k)

int main()

for (i=1;i<=m;++i)

}sort(b+1,b+b[0]+1);

size=unique(b+1,b+b[0]+1)-b-1;

build(root[0],1,size);

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

for (i=1;i<=m;++i)

else

}t--;

}fclose(stdin);

fclose(stdout);

}

其實稍微轉化一下就成模板題啦~~ code:

#include#include#include#define mid (l+r)/2

using namespace std;

struct hptree[10000000];

int root[100001],q1[2000],q2[2000],n,m;

int a[100001],a2[100001],c[100001],pos[100001],tot,del[100001];

long long ansi[50001]=;

int lowbit(int x)

long long work(int l,int r)

else

}long long bit_askless(int l,int r,int x)

long long bit_askmore(int l,int r,int x)

void insert(int last,int &i,int l,int r,int x,int flag)

void bit_ins(int i,int x,int flag)

int main()

for (i=1;i<=m;++i)

build(root[0],1,n);

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

if (a[i])

ans=work(1,a2[0]);

for (i=m;i>=1;--i)

{bit_ins(pos[del[i]],del[i],1);

if (pos[del[i]]>1) ans+=bit_askmore(0,pos[del[i]]-1,del[i]);

if (pos[del[i]]

主席樹學習筆記

問題 給定乙個n個數的序列,q次詢問第x個數到第y個數中的第k最值。我們假定是第k小。為了使討論更加簡便,我們假定序列的每個數都是不大於n的正整數。當然一般題目中元素範圍很大,但是可以用離散化預處理來做到這一點。考慮乙個比較高階的做法 令g i j 為前i個數中,值為j的數的個數。很容易用o n 2...

主席樹 學習整理

題意 給出1e5個數,向你提5000問,l到r間的第k個數是多少?主席樹,又叫可持久化線段樹或者函式式線段樹。我只知道這些了,據說是一位大神沒學會劃分樹就自己搞了這麼個替代品,結果,比原來的還要強。說一下思路 因為是求第k大的數,所以線段樹是不行的,因為數是排好序的,所以伸展樹好像也不好解決。所以主...

學習總結 主席樹

突然想起主席樹。依稀只記得演算法的大概了,所以今天又拿出來溫習了一下,畢竟學習演算法是很快的,忘掉也是很快的,而演算法一定是要運用的,否則也就沒有存在的意義了。首先主席樹是一棵線段樹,而且是乙個字首權值線段樹,支援靜態的查詢。這個演算法最大的亮點就是在原有的一棵樹的基礎上,如果想將乙個元素插入,就根...