【HDOJ】【1512】Monkey King

数据结构/可并堆



  啊……换换脑子就看了看数据结构……看了一下左偏树和斜堆,鉴于左偏树不像斜堆可能退化就写了个左偏树。

左偏树介绍:http://www.cnblogs.com/crazyac/articles/1970176.html

体会:合并操作是可并堆的核心操作(就像LCT里的access),进堆和弹堆顶都是直接调用合并操作实现的。

  而合并的实现是一个递归的过程:将小堆与大堆的右儿子合并(这里的大小指的是堆顶元素的大小),直到某个为0。(是不是有点启发式合并的感觉……)

  在合并的过程中要维护堆的形态:如果右儿子长度(或者叫深度?)大于左儿子,那就交换左右儿子。也就是说:每次要生长的时候,总是让短的一侧先生长,那么这个堆,最后就能够比较对称。

 1 //HDOJ 1512
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define rep(i,n) for(int i=0;i<n;++i)
 9 #define F(i,j,n) for(int i=j;i<=n;++i)
10 #define D(i,j,n) for(int i=j;i>=n;--i)
11 #define pb push_back
12 using namespace std;
13 inline int getint(){
14     int v=0,sign=1; char ch=getchar();
15     while(ch<‘0‘||ch>‘9‘){ if (ch==‘-‘) sign=-1; ch=getchar();}
16     while(ch>=‘0‘&&ch<=‘9‘){ v=v*10+ch-‘0‘; ch=getchar();}
17     return v*sign;
18 }
19 const int N=1e6+10,INF=~0u>>2;
20 typedef long long LL;
21 /******************tamplate*********************/
22 int n,m;
23 struct node{
24     int v,l,r,dis,f;
25     node(int v=0,int l=0,int r=0,int dis=0,int f=0):
26         v(v),l(l),r(r),dis(dis),f(f){}
27     void out(){
28         printf("%d %d %d %d %d\n",v,l,r,dis,f);
29     }
30 };
31 struct Left_tree{
32     node t[N];
33     int merge(int x,int y){
34         if (x==0) return y;
35         if (y==0) return x;
36         if (t[x].v<t[y].v) swap(x,y);
37         t[x].r=merge(t[x].r,y);
38         t[t[x].r].f=x;
39         if (t[t[x].l].dis<t[t[x].r].dis) swap(t[x].l,t[x].r);
40         if (t[x].r==0) t[x].dis=0;
41         else t[x].dis=t[t[x].r].dis+1;
42         return x;
43     }
44     int pop(int x){
45         int l=t[x].l,r=t[x].r;
46         t[l].f=l; t[r].f=r;
47         t[x].l=t[x].r=t[x].dis=0;
48         return merge(l,r);
49     }
50     int find(int x){return t[x].f==x ? x : find(t[x].f);}
51     void init(){
52         int x=0;
53         F(i,1,n){
54             x=getint();
55             t[i]=node(x);
56             t[i].f=i;
57         }
58     }
59     void solve(){
60         m=getint();
61         int x,y;
62         F(i,1,m){
63             x=getint(); y=getint();
64             int f1=find(x),f2=find(y);
65             if (f1==f2){puts("-1");continue;}
66             int t1=pop(f1),t2=pop(f2);
67             t[f1].v/=2; t1=merge(t1,f1);
68             t[f2].v/=2; t2=merge(t2,f2);
69             t1=merge(t1,t2);
70             printf("%d\n",t[t1].v);
71         }
72     }
73 }heap;
74 int main(){
75 #ifndef ONLINE_JUDGE
76     freopen("1512.in","r",stdin);
77     freopen("1512.out","w",stdout);
78 #endif
79     while(scanf("%d",&n)!=EOF){
80         heap.init(); heap.solve();
81     }
82     return 0;
83 }

时间: 2024-10-24 18:28:34

【HDOJ】【1512】Monkey King的相关文章

【HDOJ图论题集】【转】

1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How Many Tables 基础并查集★ 4 1272 小希的迷宫 基础并查集★ 5 1325&&poj1308 Is It A Tree? 基础并查集★ 6 1856 More is better 基础并查集★ 7 1102 Constructing Roads 基础最小生成树★ 8 1232

【HDU 1512】Monkey King

Monkey King Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3423    Accepted Submission(s): 1479 Problem Description Once in a forest, there lived N aggressive monkeys. At the beginning, they

hdoj 1052 Tian Ji -- The Horse Racing【田忌赛马】 【贪心】

思路:先按从小到大排序, 然后从最快的開始比(如果i, j 是最慢的一端, flag1, flag2是最快的一端 ),田的最快的大于king的 则比較,如果等于然后推断,有三种情况: 一:大于则比較,二等于在推断田的最慢的是不是比king的最快的慢,三小于则与king的最快的比較: Tian Ji -- The Horse Racing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe

hdoj 1025 Constructing Roads In JGShining&amp;#39;s Kingdom 【最长递增子序列】

Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 16262    Accepted Submission(s): 4633 Problem Description JGShining's kingdom consists of 2n(n is no mo

hdoj 1025 Constructing Roads In JGShining&#39;s Kingdom 【最长递增子序列】

Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 16262    Accepted Submission(s): 4633 Problem Description JGShining's kingdom consists of 2n(n is no mo

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ 4763】 Theme Section (KMP+strstr)

[HDOJ 4763] Theme Section Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1999    Accepted Submission(s): 947 Problem Description It's time for music! A lot of popular musicians a