zoukankan      html  css  js  c++  java
  • [HNOI2012]永无乡——Splay

    题面

      Bzoj2733

    解析

      同样是一道上课时讲的题, 对于每个连通块都维护一个Splay, 连接不同块的操作就等价于合并两棵Splay, 考虑暴力合并, 将较小的Splay断开,依次将每个点插入另外一棵Splay中, 复杂度的话,就照搬wys的PPT了:

      查找点所在平衡树的根就暴力查找,一直跳父亲,均摊(应该是吧)跳log次(最好写并查集,我是懒得写了)找到根

      然后就变成了一道查询第k小的普通平衡树了

      第一道一次AC的Splay的题,终于没有写成Spaly了, 不容易啊, 感动

     代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 100005;
    
    template<class T> void read(T &re)
    {
        re=0;
        T sign=1;
        char tmp;
        while((tmp=getchar())&&(tmp<'0'||tmp>'9')) if(tmp=='-') sign=-1;
        re=tmp-'0';
        while((tmp=getchar())&&(tmp>='0'&&tmp<='9')) re=(re<<3)+(re<<1)+(tmp-'0');
        re*=sign;
    }
    
    int n, m, q, root[maxn], a[maxn], tot;
    
    struct splay_tree{
        int s[2], val, fa, siz;
    }tr[maxn];
    
    int Find(int x)
    {
        while(tr[x].fa != 0)
            x = tr[x].fa;
        root[x] = x;
        return x;
    }
    
    void update(int x)
    {
        int ls = tr[x].s[0], rs = tr[x].s[1];
        tr[x].siz = tr[ls].siz + tr[rs].siz + 1;
    }
    
    void Rotate(int x)
    {
        int y = tr[x].fa, z = tr[y].fa, k = (tr[y].s[1] == x), w = (tr[z].s[1] == y), son = tr[x].s[k^1];
        tr[y].s[k] = son;tr[son].fa = y;
        tr[x].s[k^1] = y;tr[y].fa = x;
        tr[z].s[w] = x;tr[x].fa = z;
        update(y);update(x);
    }
    
    void Splay(int x, int to, int id)
    {
        int y, z;
        while(tr[x].fa != to)
        {
            y = tr[x].fa;z = tr[y].fa;
            if(z != to)
                Rotate((tr[y].s[0] == x) ^ (tr[z].s[0] == y)? x: y);
            Rotate(x);
        }
        if(!to)
            root[id] = x;
    }
    
    void Insert(int x, int y)
    {
        int now = root[x], ff = 0;
        while(now)
        {
            tr[now].siz ++;
            ff = now;
            if(tr[y].val< tr[now].val)
                now = tr[now].s[0];
            else
                now = tr[now].s[1];
        }
        tr[ff].s[tr[y].val > tr[ff].val] = y;
        tr[y].s[0] = tr[y].s[1] = 0;
        tr[y].fa = ff;
        Splay(y, 0, x);
    }
    
    void Del(int x, int y)
    {
        if(tr[y].s[0])
            Del(x, tr[y].s[0]);
        if(tr[y].s[1])
            Del(x, tr[y].s[1]);
        Insert(x, y);
    }
    
    int kth(int now, int x)
    {
        while(1)
        {
            int ls = tr[now].s[0], rs = tr[now].s[1];
            if(x == tr[ls].siz + 1)     return now;
            if(x <= tr[ls].siz)     now = ls;
            else     x -= tr[ls].siz + 1, now = rs;
        }
    }
    
    int main()
    {
        read(n);read(m);
        for(int i = 1; i <= n; ++i)
        {
            root[i] = ++tot;
            read(tr[root[i]].val);
            a[tr[root[i]].val] = i;
            tr[root[i]].siz = 1;
        }
        for(int i = 1; i <= m; ++i)
        {
            int x, y;
            read(x);read(y);
            int p = Find(x), q = Find(y);
            if(p != q)
            {
                if(tr[p].siz < tr[q].siz)
                    swap(p, q);
                tr[0].s[1] = p;
                Del(p, q);
            }
        }
        read(q);
        for(int i = 1; i <= q; ++i)
        {
            char opt[5];
            int x, y;
            scanf("%s", opt);
            read(x);read(y);
            if(opt[0] == 'Q')
            {
                int p = Find(x);
                if(tr[p].siz < y)
                    printf("-1
    ");
                else
                {
                    int id = kth(p, y);
                    printf("%d
    ", a[tr[id].val]);
                    Splay(id, 0, p);
                }
            }
            else 
            {
                int p = Find(x), q = Find(y);
                if(p != q)
                {
                    if(tr[p].siz < tr[q].siz)
                        swap(p, q);
                    tr[0].s[1] = p;
                    Del(p, q);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    自愿如此 四 内观
    自愿如此· 三 不做解释
    自愿如此·序言
    排序算法 (08.堆排序)
    2.2 ES6 解构赋值
    2.1 ES6 let 与 const
    ES6学习 (01. 内容概况)
    vue 技术栈进阶 (07. ajax 请求实战)
    vue技术栈进阶(06.状态持久化, 严格模式, 数据双向绑定问题)
    vue技术栈进阶(05. mutations, actions)
  • 原文地址:https://www.cnblogs.com/Joker-Yza/p/11236913.html
Copyright © 2011-2022 走看看