BZOJ 2733 永無鄉 線段樹合併

2021-08-03 15:24:17 字數 1722 閱讀 2516

time limit: 10 sec  

memory limit: 128 mb

submit: 3624  

solved: 1937 [

submit][

status][

discuss]

永無鄉包含 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 14 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

題意:給出n個帶權值的點的無向圖,做q次詢問,每次詢問包括兩個動作:1.向圖中新增一條邊  2.詢問 在與x島嶼連通的所有島嶼中,權值從小打到第k大的島嶼是哪個

題解:對所有聯通的島嶼用並查集記錄所屬,並通過動態線段樹記錄每乙個連通塊的中存在的權值,用線段樹合併,合併相互連通的島嶼,最後做單點詢問。

#include#include#include#define n 100005

using namespace std;

int a[n];

int ans[n];

int pre[n];

int root[n];

int tree[n*20];

int rchild[n*20],lchild[n*20];

int tnum;

int n,m;

int heihei;

void insert(int k,int l,int r,int root)

int mid=l+r>>1;

if(k<=mid)

else

tree[root]=tree[lchild[root]]+tree[rchild[root]];

}int find(int i)

int merge(int root1,int root2)

int query(int l,int r,int root,int k)

int main()

else

}}}

bzoj2733 永無鄉 線段樹合併

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

BZOJ2733 永無鄉 線段樹合併

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

BZOJ2733 永無鄉 splay啟發式合併

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