樹套樹入門題
樹套樹空間複雜度分析:維護乙個長度為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...