模板 可持久化平衡樹 洛谷3835

2021-08-19 08:30:39 字數 1638 閱讀 5116

1.插入x數

2.刪除x數(若有多個相同的數,因只刪除乙個,如果沒有請忽略該操作)

3.查詢x數的排名(排名定義為比當前數小的數的個數+1。若有多個相同的數,因輸出最小的排名)

4.查詢排名為x的數

5.求x的前驅(前驅定義為小於x,且最大的數,如不存在輸出-2147483647)

6.求x的後繼(後繼定義為大於x,且最小的數,如不存在輸出2147483647)

和原本平衡樹不同的一點是,每一次的任何操作都是基於某乙個歷史版本,同時生成乙個新的版本。(操作3, 4, 5, 6即保持原版本無變化)

每個版本的編號即為操作的序號(版本0即為初始狀態,空樹)

無旋treap的可持久化版本

注意細節

// luogu-judger-enable-o2

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define mp make_pair

using namespace std;

const int maxn=500000

*2;const int inf=2147483647;

typedef pair par;

struct treet[500005

*50];

int rt[maxn];

int tot;

int root;

void updata(int

x)int merge(int

x,int

y) else

}par split(int

x,int n)

intlc=t[x].lc,rc=t[x].rc;

if (n==t[lc].size)

if (n==t[lc].size+1)

if (nlc].size)

else

}int rank(int

x,int k)

if (x>t[k].data) ans+=t[t[k].lc].size+1,k=t[k].rc;

else k=t[k].lc;

}return tmp==(int)inf?ans:tmp;

}int find(int

x,int k)

}int pre(int

x,int k)

return ans;

}int net(int

x,int k)

return ans;

}void insert(int &rt,int

x)void del(int &rt,int

x)int n;

int main()

else

if(op==4) printf("%d\n",find(x,rt[i]));

else

if(op==5) printf("%d\n",pre(x,rt[i]));

else

printf("%d\n",net(x,rt[i]));

}return

0;}

洛谷P3835 模板 可持久化平衡樹

本題為題目 普通平衡樹 的可持久化加強版。資料已經經過強化 插入x數 刪除x數 若有多個相同的數,因只刪除乙個,如果沒有請忽略該操作 查詢x數的排名 排名定義為比當前數小的數的個數 1。若有多個相同的數,因輸出最小的排名 查詢排名為x的數 求x的前驅 前驅定義為小於x,且最大的數,如不存在輸出 21...

洛谷 P3835 模板 可持久化平衡樹

可持久化平衡樹 可持久化 treap 1.插入 x 2.刪除 x 3.查詢 x 的排名 4.查詢排名為 x 的數 5.求 x 的前驅 6.求 x 的後繼 每次操作都基於某一歷史版本,同時生成乙個新的版本 include include include define maxn 500010 using...

洛谷 P3835 模板 可持久化平衡樹

題目傳送門 洛谷p3835。題意簡述 題面說的很清楚了。題解 考慮建立一棵每個節點都表示乙個版本的樹。以初始版本 0 為根。對於第 i 個操作,從 v i 向 i 連一條邊,而邊權則是 opt i 和 x i 的二元組,表示經過這條邊上操作,可以達到下乙個狀態。考慮使用權值樹狀陣列維護操作。只需要實...