Zoj 2112 線段樹套Treap

2021-08-07 17:41:32 字數 1506 閱讀 6662

樹套樹入門題

樹套樹空間複雜度分析:維護乙個長度為n的序列,線段樹的結點數一般為4n,而treap則是對於每乙個元素(包括重複出現的)都需要乙個空間,那麼第1層的所需要的空間為(1*n),第二層為(2*n/2)……所以其實為o(h)*n.

那麼所需的空間為o(

nlog

n)但在實際運用中,所形成的線段樹往往不是完全二叉樹,即最後一層並不滿,所以上述空間會非常吃緊,所以一般為o(

4nlo

g4n)

即結點數的lo

g 倍

ps:大常數選手跑了4000ms

#include

#include

#include

#include

#include

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

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

using

namespace

std;

const

int n=200000+10,m=1300001;

int l[m],r[m],s[m],v[m],w[m],rnd[m],a[n],

n,m,sz,root[n],tmp;

void update(int k)

void rturn(int &k)

void lturn(int &k)

void insert(int &k,int val)

s[k]++;

if(val==v[k]) w[k]++;

else

if(val>v[k])

if(l[k]*r[k]==0)k=l[k]+r[k];

else

if(rnd[r[k]]else rturn(k),del(k,val);

}else

if(val>v[k])

s[k]--,del(r[k],val);

else s[k]--,del(l[k],val);

}void find(int k,int val)

}void build(int k,int l,int r,int pos,int val)

void change(int k,int l,int r,int pos,int val,int del)

void que(int k,int l,int r,int ql,int qr,int val)

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

if(qr<=mid)que(k<<1,l,mid,ql,qr,val);

else

if(ql>mid)que(k<<1|1,mid+1,r,ql,qr,val);

else

}int main()

else

printf("%d\n",l);}}

}return

0;}

ZOJ 2112 線段樹套平衡樹

題目大意 給定乙個數列,定義兩種操作 1 修改第n個數的值 2 求 l,r 區間內第k大的值。方法 線段樹維護區間,treap樹維護第k大 splay當然也可以 樹套樹第一題。沒想到真的是每個線段樹上的節點建一棵平衡樹。然後修改值就是在所有相關區間內的平衡樹里,erase乙個值再insert乙個值。...

zoj 2112 主席樹套樹狀陣列

現在把主席樹的原理給弄清楚了,從i 1開始,每次新插入乙個數,就為他建一棵線段樹 當然第一次i 0的時候是建一棵空樹 線段樹裡面儲存的是1 i的樹的位置情況 簡單來說,如果有m個樹,則每棵線段樹都是範圍為1 m的,至於1 i沒有m個那就先讓它空著不管,我只負責1 i裡面的數的位置情況插入到線段樹裡面...

zoj 2112 主席樹套樹狀陣列 優化

題解思路 如果直接對原來的陣列建立主席樹套樹狀陣列的空間複雜度是 n m log n m log n m 這樣明顯 那麼我們可以對原來的數組建主席樹模型,空間複雜度就是n logn,對m裡面的修改建主席樹套樹狀陣列空間複雜度是m logm logm明顯小了很多。include define lson...