Submit address: Click to open the link
N (n <= 10 ^ 5) a monkey. Initially, each monkey is the Monkey King in his/her group. Each monkey has an initial power value. These monkeys will have m meetings. Each time two monkeys x and y meet, if X and Y belong to the same monkey group, output-1; otherwise, the monkey power value of X and Y is halved, then merge the two monkey groups. The Monkey King has the highest force value in the new monkey group. Output the power of the new Monkey King.
Analysis: Query, merge, and obtain the maximum value of a set. You can use the dataset and left-side tree to solve the problem.
# Include <cstdio> # include <cstring> # include <iostream> # include <algorithm> using namespace STD; const int maxn = 200000; int tot, V [maxn], L [maxn], R [maxn], d [maxn], F [maxn]; int findset (int x) {return f [x] = x? X: F [x] = findset (F [x]);} int merge (int x, int y) {If (! X) return y; If (! Y) return X; If (V [x] <V [y]) Swap (x, y); // R [x] = Merge (R [X], y); // recursively merge the right subtree and y f [R [x] = X; // update T's right subtree root if (d [L [x] <D [R [x]) // maintain heap swap (L [X], R [x]); D [x] = d [R [x] + 1; return X;} int Init (int x) {tot ++; V [tot] = x; F [tot] = tot; L [tot] = R [tot] = d [tot] = 0;} int insert (int x, int y) {return Merge (x, INIT (y);} int top (int x) {return V [X];} int POP (int x) {int L = L [X], r = R [X]; F [l] = L; F [R] = R; V [x]/= 2; R [x] = L [x] = d [x] = 0; return merge (L, R );} void solve (int x, int y) {int left = POP (x), Right = POP (y); left = Merge (left, x); Right = Merge (right, y); left = Merge (left, right); printf ("% d \ n", top (left);} int main () {int n, m, I, x, Y; while (~ Scanf ("% d", & N) {tot = 0; for (I = 1; I <= N; ++ I) {scanf ("% d ", & X); Init (x) ;}scanf ("% d", & M); for (I = 1; I <= m; ++ I) {scanf ("% d", & X, & Y); int FX = findset (x), FY = findset (y); If (FX = FY) {printf ("-1 \ n") ;}else {solve (FX, FY) ;}} return 0 ;}/ * 520161010452 33 4855-110 */