Test instructions: At first there were n monkeys, each with a power value. And they didn't know each other, and then they fought M-times. Two monkeys every two times a, a, A and B struggle is that a and a will pull out one of their strongest friends from their own circle of friends, and then the strongest of the two monkeys hit, after the end of the two monkeys to halve the power value. And all two of the monkey's circle of friends know each other (that is, they will never fight again). The problem is that for each struggle, if a A and a friend, then output-1, otherwise the output struggle after their friends in the circle of the strongest monkey power value.
Analysis: To represent the merge lookup operation of the collection is the best, and to maintain the maximum value each time, you can use the large top heap, but also to facilitate the consolidation between the heap operations, the use of left-leaning tree is the best. This problem is also equivalent to the left-leaning tree exercises.
#include <iostream>using namespace std; #define N 100005class cleftisttree{private:struct set//and check set {int m _iparent; parent node int m_itreeroot; The root node of the left-leaning tree};struct node//left-biased tree nodes {int m_ileft; Left dial hand tree int m_iright; Right sub-tree int m_ivalue; Key value int M_idis; Distance};p Ublic:cleftisttree () {}~cleftisttree () {}void readvalue (int n), int Process (int a,int b);p Rivate:int FindRoot ( int x); void unionset (int a,int b,int p); int mergetree (int a,int b); Set M_sset[n]; Node m_snode[n];}; int cleftisttree::mergetree (int a,int b) {if (a==0) return b;if (b==0) return a;if (m_snode[a].m_ivalue<m_snode[b].m_ Ivalue) Swap (A, b); The value is large as the root node (equivalent to the large top heap) m_snode[a].m_iright=mergetree (m_snode[a].m_iright,b); Merge to right subtree if (M_snode[m_snode[a].m_ileft].m_idis<m_snode[m_snode[a].m_iright].m_idis)//Make sure it is a left-leaning tree swap (M_snode[a] . m_ileft,m_snode[a].m_iright); if (m_snode[a].m_iright==0) m_snode[a].m_idis=0; Update distance Elsem_snode[a].m_idis=m_snode[m_snode[a].m_iright].m_idis+1;return A;} void CLeftisttree::unionset (int a,int b,int p) {if (a<b) {m_sset[a].m_iparent=b;m_sset[b].m_itreeroot=p;} Else{m_sset[b].m_iparent=a;m_sset[a].m_itreeroot=p;}} int cleftisttree::findroot (int x) {int root=x;int parent;while (root!=m_sset[root].m_iparent) root=m_sset[root].m_ Iparent;parent=m_sset[x].m_iparent;while (parent!=root)//path compression {M_sset[x].m_iparent=root;x=parent;parent=m_sset[x ].m_iparent;} return root;} int Cleftisttree::P rocess (int a,int b) {int x,y,p,q;if (FindRoot (a) ==findroot (b))//In the same collection Return-1;x=m_sset[findroot (a)]. M_itreeroot; Find the root of the left-leaning Tree y=m_sset[findroot (b)].m_itreeroot;p=mergetree (m_snode[x].m_ileft,m_snode[x].m_iright); Remove the root, combine left and right subtree to left partial tree q=mergetree (m_snode[y].m_ileft,m_snode[y].m_iright); m_snode[x].m_ivalue/=2;m_snode[x].m_idis=m _snode[x].m_ileft=m_snode[x].m_iright=0; The value of the two largest monkeys is halved m_snode[y].m_ivalue/=2;m_snode[y].m_idis=m_snode[y].m_ileft=m_snode[y].m_iright=0;p=mergetree (p,x) ; Insert the original tree Q=mergetree (q,y);p =mergetree (p,q) respectively; Get a complete Tree Unionset (FindRoot (a), FindRoot (b), p); And check the merge return m_snode[p].m_ivalue;} void Cleftisttree::readvalue (int n) {int i;for (i=1;i<=n;i++) {scanf ("%d", &m_snode[i].m_ivalue); m_snode[i].m_ idis=m_snode[i].m_ileft=m_snode[i].m_iright=0;m_sset[i].m_iparent=i;m_sset[i].m_itreeroot=i;}} Cleftisttree Left_tree;int Main () {int n,m,x,y;while (scanf ("%d", &n) ==1) {Left_tree. ReadValue (n); scanf ("%d", &m), while (m--) {scanf ("%d%d", &x,&y);p rintf ("%d\n", Left_tree. Process (x, y));}} return 0;}
HDU ACM 1512 Monkey king-> left bias tree + and check set