zoukankan      html  css  js  c++  java
  • Monkey King

    传送门

    我觉得这个题目翻译的特别好,真的。

    这个就是左偏树的模板题啦。每次找到这俩猴子所属的堆,然后如果不一样的话,就把两个堆里面最牛叉的两只猴子战斗力减成一半。我们用左偏树维护,取猴子的时候直接取顶端,然后我们把这个点的权值改成原来一半,重新合并就行啦。

    这题在做的时候莫名MLE……后来发现是自己在删除操作的时候忘记清空这个点的左右儿子信息了。一般左偏树的题是不需要清空,但是这道题里面需要修改之后合并回来,如果不清空可能会出很严重的问题。

    看一下代码。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<set>
    #include<queue>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define lowbit(x) x & (-x)
    
    using namespace std;
    typedef long long ll;
    const int M = 500005;
    const int INF = 1000000009;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    int n,m,root[M],lc[M],rc[M],val[M],dis[M],x,y;
    
    int merge(int x,int y)
    {
        if(!x || !y) return x | y;
        if(val[x] < val[y]) swap(x,y);
        rc[x] = merge(rc[x],y);
        root[rc[x]] = x;
        if(dis[lc[x]] < dis[rc[x]]) swap(lc[x],rc[x]);
        dis[x] = dis[rc[x]] + 1;
        return x;
    }
    
    int del(int x)
    {
        int l = lc[x],r = rc[x];
        root[lc[x]] = lc[x],root[rc[x]] = rc[x];
        lc[x] = rc[x] = dis[x] = 0;
        return merge(l,r);
    }
    
    int find(int x)
    {
        return (root[x] == x) ? x : root[x] = find(root[x]);
    }
    
    void clear()
    {
        memset(root,0,sizeof(root));
        memset(val,0,sizeof(val));
        memset(dis,0,sizeof(dis));
        memset(lc,0,sizeof(lc));
        memset(rc,0,sizeof(rc));
        dis[0] = -1;
    }
    
    int main()
    {
        while(scanf("%d",&n) != EOF)
        {
        clear();
        rep(i,1,n) val[i] = read(),root[i] = i;
        m = read();
        rep(i,1,m)
        {
            x = read(),y = read();
            int r1 = find(x),r2 = find(y);
            if(r1 == r2) printf("-1
    ");
            else
            {
            val[r1] >>= 1,val[r2] >>= 1;
            int f = del(r1),g = del(r2);
            int k1 = merge(f,r1),k2 = merge(g,r2);
            int k3 = merge(k1,k2);
            printf("%d
    ",val[k3]);
            }
        }
        }
        return 0;
    }
  • 相关阅读:
    Haskell Interactive Development in Emacs
    Access Java API in Groovy Script
    手工设置Eclipse文本编辑器的配色
    Color Theme of Emacs
    Gnucash的投资记录
    Special Forms and Syntax Sugars in Clojure
    Use w3m as Web Browser
    SSE指令集加速之 I420转BGR24
    【图像处理】 增加程序速度的方法
    TBB 入门笔记
  • 原文地址:https://www.cnblogs.com/captain1/p/9801223.html
Copyright © 2011-2022 走看看