洛谷 p3391
/*splay只記模板是很困難的,而且真正運用時易生疏出錯,所以必須理解,在看**前先弄懂
splay的原理,這篇**是帶注釋的splay模板,題目來自洛谷p3391 ———————————by 520*/
#include#define il inline
using namespace std;
const int n = 100005;
il int gi()
int n, m, tot, root, siz[n], fa[n], lazy[n], key[n], tree[n][2], ans[n];
/*root為根節點,siz儲存子樹節點數,fa儲存父節點,lazy是懶惰標記用來標記區間翻轉操作,key陣列儲存原數列,tree為
splay樹,ans儲存答案*/
il void pushup(int rt) //作用類似與線段樹
il void pushdown(int now)
}il int getson(int x) //getson判斷x是其父親的右兒子還是左兒子
il void rotate(int x) //旋轉操作,直接寫在乙個函式裡,可以稱為上旋
il void splay(int x, int i)
/*若x和y為相同偏向,則進行zig-zig或zag-zag操作*/
else /*否則進行zig-zag或zag-zig操作*/
/*注意rotate函式中已經包含了這四種操作情況了*/
} }}il int find(int x) //查詢x的位置 }}
il int build(int l, int r, int rt) //建樹過程和線段樹類似
il void print(int now) //輸出時中序遍歷,按左根右輸出
int main()
print(root);
for (int i = 1; i <= n; i++)printf("%d ", ans[i + 1]); //輸出時將前驅還原為原數
return 0;
}
poj 3580&bzoj 1895
#include #include #include #include #include using namespace std;
typedef long long ll;
const int maxn = 2e5 + 7;
const int inf = 1e9;
int n, m;
int ch[maxn][2]; //0做孩子, 1右孩子
int f[maxn]; //每個節點的父親
int sz[maxn]; //每個節點為根子樹的大小
int val[maxn]; //這個節點所表示的值
int cnt[maxn]; //這個節點所表示值的數量
int mi[maxn]; //這個節點子樹的最小值
int rev[maxn]; //反轉標記
int lazy[maxn]; //延遲標記
int root; // splay的根
int tot; //樹所有的節點數量
void swap(int &x, int &y)
int min(int x, int y)
void update_rev(int x) //更新反轉
void update_add(int x, int v)
void newnode(int rt, int v, int fa)
void delnode(int rt) //為了**空間,其實沒什麼太大的用處
void pushup(int x) //跟線段樹一樣,從下往上不斷更新
void pushdown(int x) //向下傳遞lazy 跟 rev
if (rev[x]) }
void build(int &rt, int l, int r, int fa) //rt是節點編號,節點的大小代表了兩個數字置的相對順序
void rotate(int x, int k) // k = 0左旋, k = 1右旋
void splay(int x, int goal)
} pushup(x);
if (goal == 0) root = x;
}//以x為根的子樹 的極值點 0 極小 1 極大
int extreme(int x, int k)
//以節點編號x為根的子樹 第k個數的節點編號
int kth(int x, int k)
//區間交換
void exchange(int l1, int r1, int l2, int r2)
//區間翻轉
void reversal(int l, int r)
//區間加
void add(int l, int r, int v)
//在第k個數後插入值為x的節點
void insert(int k, int x)
//刪除第k位置的數
void delete(int k)
// 獲取區間最大值
//int get_max(int l,int r)
////獲取區間最小值
int get_min(int l, int r)
void init(int n)
char s[12];
int main()
else if (s[0] == 'i')
else if (s[0] == 'm')
else if (s[0] == 'd')
else if (s[3] == 'e')
else
}return 0;
}
文藝平衡樹(splay模板)
題幹 splay模板,要求維護區間反轉。splay是一種碼量小於treap,但支援排名,前驅後繼等treap可求的東西,也支援區間反轉的平衡樹。但是有兩個壞處 1.splay常數遠遠大於treap以及stl中的set。2.沒有可持久化splay,但有可持久化treap。下面是 1.pushup以及p...
模板 文藝平衡樹(Splay)
這是一道經典的splay模板題 文藝平衡樹。輸入格式 第一行為n,m n表示初始序列有n個數,這個序列依次是 1,2,cdots n 1,n 1,2,n 1,n m表示翻轉操作次數 接下來m行每行兩個數 l,r l,r 資料保證 1 leq l leq r leq n1 l r n 輸出格式 輸出一...
文藝平衡樹 Splay
鏈結 splay板子題 結果還調了很久的題,這就是搞文化課的 顯然維護陣列下標,使得splay的中序遍歷始終為當前數列 值得注意 旋轉時始終要記得更新節點 注意更新root節點 每次寫都忘.jpg includeusing namespace std const int maxn 100000 10...