"The main topic"
There lived N (n<=10000) monkeys in a forest. In the beginning, they were strangers. But as time goes by, monkeys struggle, but that only happens between the two monkeys who don't know each other. During the battle, two monkeys would ask the strongest of the monkeys he knew (possibly himself) to fight. After the battle, the two monkeys knew each other. Each monkey has a strong value, but when the two monkeys are asked to fight, their strength will be halved (for example, 10 will be reduced to 5, 5 will be reduced to 2). Now give each monkey's initial strength value, give the M battle, if the battle of two monkeys do not know, then output battle two monkeys know the strongest monkey in the monkey's strong value, otherwise output-1.
Ideas
Left-leaning tree naked, a monkey is a left-leaning tree, and then each fight will first delete the heap, the strength of the value of half inserted back to the original heap, and then merge two heap, the final output heap top can be.
About left-leaning tree, see this ppt.
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <algorithm>5 using namespacestd;6 Const intinf=0x7fffffff;7 Const intmaxn=100000+ -;8 structnode9 {Ten intKey,dis; One intLson,rson; A intfather; - }; - node LTREE[MAXN]; the intN; - - voidBuildintXintk) - { +ltree[x].key=K; -Ltree[x].father=x; +ltree[x].lson=ltree[x].rson=0; ALtree[x].dis= (x==0)?-1:0; at } - - intFindintx) - { - if(ltree[x].father==x)returnx; - Else return(Find (Ltree[x].father)); in } - to intMergeintXinty) + { - if(x==0)returny; the if(y==0)returnx; * if(ltree[x].key<ltree[y].key) Swap (x, y); $ltree[x].rson=merge (ltree[x].rson,y);Panax Notoginseng int&l=ltree[x].lson,&r=Ltree[x].rson; -Ltree[l].father=ltree[r].father=x; the if(ltree[l].dis<Ltree[r].dis) Swap (l,r); + if(r==0) ltree[x].dis=0; A Elseltree[x].dis=ltree[l].dis+1; the returnx; + } - $ intDelintRT) $ { - intL=Ltree[rt].lson; - intR=Ltree[rt].rson; theLtree[l].father=l; -Ltree[r].father=R;Wuyiltree[rt].dis=ltree[rt].lson=ltree[rt].rson=0; the returnmerge (l,r); - } Wu - intSolveintXinty) About { $ltree[x].key>>=1; -ltree[y].key>>=1; - intLeft,right; -left=del (x); Aright=del (y); +left=merge (left,x); theright=merge (right,y); -left=merge (left,right); $ returnLtree[left].key; the } the the voidInit () the { - for(intI=1; i<=n;i++) in { the intStrong; thescanf"%d",&strong); About build (I,strong); the } theBuild0,0); the } + - voidGet_ans () the {Bayi intQ; thescanf"%d",&q); the for(intI=0; i<q;i++) - { - intx, y; thescanf"%d%d",&x,&y); the intFx=find (x), fy=find (y); the if(fx==fy) cout<<-1<<Endl; the ElseCout<<solve (fx,fy) <<Endl; - } the } the the intMain ()94 { the while(SCANF ("%d", &n)! =EOF) the { the init ();98 Get_ans (); About } - return 0; 101}
"Left-leaning tree" Hdu1512-monkey King