51nod 1525 重組公司

2021-08-15 18:54:32 字數 1364 閱讀 9792

有n個人在公司裡面工作。員工從1到n編號。每乙個人屬於乙個部門。剛開始每乙個人在自己的部門負責自己的專案,這樣的話公司裡面就有n個部門。

然而,公司內部出現了危機,需要合併一些部門,以提高工作效率。team(person) 表示person這個人所在的部門。有以下兩種合併操作:

1.    合併 team(x) 和 team(y)。 x和 y (1≤x,y≤n)是員工編號。如果team(x) 和 team(y)是同乙個部門,那麼就不操作。

2.    合併team(x),team(x+1),...,team(y),x 和 y (1≤x≤y≤n)是員工編號。

有一些查詢操作,查詢員工x 和 y (1≤x,y≤n)是否屬於同一部門。

input

單組測試資料。

第一行有兩個整數n 和 q (1≤n≤200000, 1≤q≤500000)表示員工的數目和運算元目。

接下來q行,每行的格式是type x y。type∈。如果type=1 或者 type=2,那麼表示第一種或者第二種合併操作。如果type=3,表示查詢員工x和y是否屬於同一部門。

output

對於第三種查詢,如果屬於同一部門輸出yes,否則輸出no。
input示例

樣例輸入1

8 63 2 5

1 2 5

3 2 5

2 4 7

2 1 2

3 1 7

output示例

樣例輸出1

noyes

yes

思路:

並查集,par陣列用來記錄各節點的父子關係,prev陣列是用來記錄每個節點左邊最近的臨界點,主要是為了避免逐個查詢範圍內的每乙個節點。

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

const int maxn = 200005;

int par[maxn];

int prev[maxn];

int read()

return x;}

int find(int *p, int x)

else

return p[x];}

void merge(int *p, int x, int y)

void mergexy(int x, int y)}

int main()

int t, x, y;

while (q--)

else if (t == 2)

else

}return 0;

}

51nod2553 雙重祖先

給定兩顆有根樹,兩顆樹均有 n 個節點,且跟均為 1 號點 問有多少對 u,v 滿足在給定的兩顆樹中 u 均為 v 的祖先 先重鏈剖分第一顆樹,處理出剖分序後在第二顆樹上 dfs 每 dfs 到乙個點就把其加入第一顆樹對應的剖分序的位置,可以用樹狀陣列維護 那麼假設現在 dfs 到的點為點 x 那麼...

51nod 1091 重疊的線段(貪心)

題幹 x軸上有n條線段,每條線段包括1個起點和終點。線段的重疊是這樣來算的,10 20 和 12 25 的重疊部分為 12 20 給出n條線段的起點和終點,從中選出2條線段,這兩條線段的重疊部分是最長的。輸出這個最長的距離。如果沒有重疊,輸出0。input 第1行 線段的數量n 2 n 50000 ...

51nod 貪心入門

有若干個活動,第i個開始時間和結束時間是 si,fi 活動之間不能交疊,要把活動都安排完,至少需要幾個教室?分析 能否按照之一問題的解法,每個教室安排盡可能多的活動,即按結束時間排序,再貪心選擇不衝突的活動,安排乙個教室之後,剩餘的活動再分配乙個教室,繼續貪心選擇 反例 a 1,2 b 1,4 c ...