突然不會寫學習筆記了...
反正是給自己看的
那就想到哪寫到哪吧
不基於旋轉而基於暴力重構的平衡樹
採用懶惰刪除法 每次刪除只打標記,在重構時統一刪除
如果某個點的子樹過於不平衡或刪除了過多的元素 那就需要進行重構
重構時暴力dfs整棵子樹,碰見打了刪除標記的節點就扔進記憶體池,否則按照中序遍歷存下來,然後遞迴建滿二叉樹即可。
**長這樣:
void dfs(int &len,int x)
int build(int l,int r)
void pia(int x)
一定要注意及時更新資訊
普通平衡樹的**:
#pragma gcc optimize(2)
#includeusing std::min;
using std::max;
using std::swap;
using std::vector;
typedef double db;
typedef long long ll;
#define pb(a) push_back(a)
#define pii std::pair#define all(a) a.begin(),a.end()
#define mp(a,b) std::make_pair(a,b)
const int n=1e6+5;
const db alph=0.75;
#define ls ch[x][0]
#define rs ch[x][1]
int n,tot,dp[n],dc,cz[n];
int sze[n],ch[n][2],cnt[n];
int val[n],root,del[n],fa[n];
int newnode()
bool chk(int x)
void dfs(int &len,int x)
void pushup(int x)
int build(int l,int r)
void pia(int x)
int ins(int x,int v,int f,int &flag) int d=val[x]=rk) erase(ls,rk,flag);
else erase(rs,rk-sze[ls]-!del[x],flag);
if(chk(x)) flag=x;
}int kth(int x,int k) else
}int find(int x,int k)
int getint()
signed main()
if(opt==3) printf("%d\n",find(root,x)+1);
if(opt==4) printf("%d\n",kth(root,x));
if(opt==5) printf("%d\n",kth(root,find(root,x)));
if(opt==6) printf("%d\n",kth(root,find(root,x+1)+1));
} return 0;
}
突然想到了一種不用記錄fa的方法哈哈哈哈哈!!!
我們需要記錄fa的本質原因是因為在重構的時候要更改fa的ch陣列
既然這樣我們傳參的時候傳乙個pair包括x和fa[x]不就好了!
哈哈哈哈哈我真是個小機靈鬼
替罪羊樹學習筆記
教練講旋轉的時候摸魚去了,然後就不會旋轉操作了t t,那怎麼辦呢,要做題的啊,誒,替罪羊樹好像是不用旋轉的誒qwq,就它了。替罪羊樹這樣直接講不直觀,還是看題來講吧。上題 洛谷 p3369 模板 普通平衡樹 概念 思想 替罪羊樹屬於平衡樹的一種,但是他維護平衡的方式不是複雜的旋轉,而是直接把這棵子樹...
替罪羊樹學習筆記
部落格咕咕咕了好久 最近會逐步繼續恢復更新部落格的。最近又在學習二叉搜尋樹。實測發現替罪羊樹快的飛起 時間約splay的1 2 寫起來還比較簡單,決定來一波。那為什麼還要用splay呢?因為splay是序列之王!還能維護lct!你要用非旋treap fhq treap 我也沒意見 替罪羊樹的主要思想...
替罪羊樹學習筆記
替罪羊樹是一種平衡樹。然而它既不能可持久化,又不能維護區間。所以把它發明出來幹嘛?然而它可以維護子樹內資訊。這個是一眾平衡樹都不能做到的功能。它維護平衡的方式和普通的平衡樹瘋狂旋轉不太一樣。它是如果這個子樹不平衡就把這個子樹拍平了重構。具體地,如果左子樹的節點數和右子樹的節點數比值超過某個值或小於某...