码迷,mamicode.com
首页 > 其他好文 > 详细

HDOJ 1512 几乎模板的左偏树

时间:2016-11-10 02:42:33      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:lis   ios   isp   printf   map   merge   for   表示   ack   

题目大意:有n个猴子。每个猴子有一个力量值,力量值越大表示这个猴子打架越厉害。如果2个猴子不认识,他们就会找他们认识的猴子中力量最大的出来单挑,单挑不论输赢,单挑的2个猴子力量值减半,这2拨猴子就都认识了,不打不相识嘛。现在给m组询问,如果2只猴子相互认识,输出-1,否则他们各自找自己认识的最牛叉的猴子单挑,求挑完后这拨猴子力量最大值。

左偏大根加并查

代码都懒的贴了...

 

技术分享
 1 #include <iostream>
 2 #include <fstream>
 3 #include <sstream>
 4 #include <algorithm>
 5 #include <string>
 6 #include <set>
 7 #include <map>
 8 #include <utility>
 9 #include <queue>
10 #include <stack>
11 #include <list>
12 #include <vector>
13 #include <cstdio>
14 #include <cstdlib>
15 #include <cstring>
16 #include <cmath>
17 #include <ctime>
18 using namespace std;
19 const int maxn = 100010;
20 struct node {
21         int l,r,dis,val,par;
22 } heap[maxn];
23 int N, M;
24 int find ( int &x ) {
25     return heap[x].par == x ? x : heap[x].par = find ( heap[x].par );
26 }
27 int merge(int rt1,int rt2)  
28 {  
29     if (rt1==0) return rt2;  
30     if (rt2==0) return rt1;  
31     if ( heap[rt2].val>heap[rt1].val )swap(rt1,rt2);  
32     heap[rt1].r = merge(heap[rt1].r,rt2);
33     heap[heap[rt1].r].par = rt1;
34     if ( heap[ heap[rt1].l ].dis < heap[ heap[rt2].r ].dis ) 
35          swap ( heap[rt1].l, heap[rt1].r ); 
36     else heap[rt1].dis = heap[ heap[rt1].r ].dis + 1;
37     return rt1;  
38 }  
39 int push ( int x, int y ) {
40     return merge ( x, y );       
41 }
42 int pop ( int &x ) {
43     int l = heap[x].l; 
44     int r = heap[x].r; 
45     heap[l].par = l;
46     heap[r].par = r;
47     heap[x].l = heap[x].r = heap[x].dis = 0;   
48     return merge ( l, r );  
49 }
50 bool scan_d(int &num) {
51     char in;bool IsN=false;
52     in=getchar();
53     if(in==EOF) return false;
54     while(in!=-&&(in<0||in>9)) in=getchar();
55     if(in==-){ IsN=true;num=0;}
56     else num=in-0;
57     while(in=getchar(),in>=0&&in<=9){
58             num*=10,num+=in-0;
59     }
60     if(IsN) num=-num;
61     return true;
62 }
63 int main() {
64     while ( scan_d ( N ) ) {
65          for ( int i = 1; i <= N; ++ i ) {
66               scan_d ( heap[i].val );
67               heap[i].l = heap[i].r = heap[i].dis = 0;
68               heap[i].par = i;    
69          }
70          scan_d ( M );
71          int a, b, x, y;
72          while ( M -- ) {
73                 scan_d (a); scan_d (b);
74                 x = find ( a );
75                 y = find ( b ); 
76                 if ( x == y ) {
77                     puts ( "-1" );     
78                 } else {
79                     heap[x].val /= 2;
80                     int px = push ( pop ( x ), x );  
81                     heap[y].val /= 2;
82                     int py = push ( pop ( y ), y );  
83                     
84                     printf ( "%d\n", heap[ merge ( px, py ) ].val );      
85                 }    
86          } 
87     }
88     return 0;
89 }
View Code

 

HDOJ 1512 几乎模板的左偏树

标签:lis   ios   isp   printf   map   merge   for   表示   ack   

原文地址:http://www.cnblogs.com/Geek-xiyang/p/6049388.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!