BZOJ2733 永無鄉 splay啟發式合併

2022-05-08 05:00:08 字數 2039 閱讀 1265

作者部落格:

永無鄉包含 n 座島,編號從 1 到 n,每座島都有自己的獨一無二的重要度,按照重要度可 以將這 n 座島排名,名次用 1 到 n 來表示。某些島之間由巨大的橋連線,通過橋可以從乙個島 到達另乙個島。如果從島 a 出發經過若干座(含 0 座)橋可以到達島 b,則稱島 a 和島 b 是連 通的。現在有兩種操作:b x y 表示在島 x 與島 y 之間修建一座新橋。q x k 表示詢問當前與島 x連通的所有島中第 k 重要的是哪座島,即所有與島 x 連通的島中重要度排名第 k 小的島是哪 座,請你輸出那個島的編號。 

輸入檔案第一行是用空格隔開的兩個正整數 n 和 m,分別 表示島的個數以及一開始存在的橋數。接下來的一行是用空格隔開的 n 個數,依次描述從島 1 到島 n 的重要度排名。隨後的 m 行每行是用空格隔開的兩個正整數 ai 和 bi,表示一開始就存 在一座連線島 ai 和島 bi 的橋。後面剩下的部分描述操作,該部分的第一行是乙個正整數 q, 表示一共有 q 個操作,接下來的 q 行依次描述每個操作,操作的格式如上所述,以大寫字母 q 或b 開始,後面跟兩個不超過 n 的正整數,字母與數字以及兩個數字之間用空格隔開。 對於 20%的資料 n≤1000,q≤1000 

對於 100%的資料 n≤100000,m≤n,q≤300000 

對於每個 q x k 操作都要依次輸出一行,其中包含乙個整數,表 示所詢問島嶼的編號。如果該島嶼不存在,則輸出-1。 

5 1 

4 3 2 5 1 

1 2 

7q 3 2 

q 2 1 

b 2 3 

b 1 5 

q 2 1 

q 2 4 

q 2 3 -12

512正解:$splay$啟發式合併

解題報告:

昨天用乙個$log$的線段樹合併切掉了這道題,今天試著用$splay$又寫了一遍,帶$splay$的東西果然各種寫萎qaq

複雜度也是玄學…

每個節點維護一棵$splay$,每次合併的時候$size$小的往大的上面合。

具體做法就是把小的那棵樹拆了,乙個乙個往大的裡面扔…聽上去很暴力,但是複雜度確實是正確的。

查詢的話就是$splay$基本的查詢第$k$小數操作了。

總複雜度:$o(nlog^2 n)$

//it is made by ljh2000

#include #include #include #include #include #include using namespace std;

typedef long long ll;

const int maxn = 100011;

int n,m,q,w[maxn],pos[maxn],f[maxn],root[maxn],father[maxn];

int size[maxn],tr[maxn][2],dui[maxn],head,tail;

char ch[12];

inline int find(int x)

inline int getint()

inline void rotate(int x,int &rt)

inline void splay(int x,int &rt)

rotate(x,rt); }}

inline void insert(int x,int &rt,int fa)

size[rt]++;

if(w[x]<=w[rt]) insert(x,tr[rt][0],rt);

else insert(x,tr[rt][1],rt);

}inline void merge(int x,int y)

}inline int kth_query(int rt,int k)

}inline void work()

q=getint();

while(q--)

printf("%d\n",pos[ kth_query(root[find(x)],y) ]);

} else merge(find(x),find(y)); }}

int main()

bzoj2733 永無鄉 線段樹合併

這道題是一道經典的平衡樹 啟發式合併吧。那麼考慮用可持久化線段樹來寫。對每乙個節點儲存一棵線段樹表示所在塊的編號的集合 因此可以乙個塊值儲存一棵樹 然後合併的時候就地櫃合併左子節點和右子節點,然後更新節點的值即可。時空複雜度o nlogn ac 如下 include include include ...

BZOJ 2733 永無鄉 線段樹合併

time limit 10 sec memory limit 128 mb submit 3624 solved 1937 submit status discuss 永無鄉包含 n 座島,編號從 1 到 n,每座島都有自己的獨一無二的重要度,按照重要度可 以將這 n 座島排名,名次用 1 到 n ...

BZOJ2733 永無鄉 線段樹合併

永無鄉包含 n 座島,編號從 1 到 n,每座島都有自己的獨一無二的重要度,按照重要度可 以將這 n 座島排名,名次用 1 到 n 來表示。某些島之間由巨大的橋連線,通過橋可以從乙個島 到達另乙個島。如果從島 a 出發經過若干座 含 0 座 橋可以到達島 b,則稱島 a 和島 b 是連 通的。現在有...