有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 ...