Splay树(HDU - 5493 Queue)

题目链接
蒻苟还是蒻苟,知道是线段树,写不出来。。。只能尝试用Splay维护。还好就是一个定点插入问题,比较好维护。可是感觉还是很有用的,890ms比线段树+二分快了一点,嘻嘻。(尝试自我安慰) 不过,以后的定点插入就可以用这个作为板子了。。还算不亏。
下面是ac代码:

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define ll long long
using namespace std;
const int N = 2e5+5;
struct Node
{
    int fa,ch[2],val,cnt,si;
}tr[N];
int cnt,root;
inline void update(int x)
{
    tr[x].si=tr[tr[x].ch[0]].si+tr[tr[x].ch[1]].si+tr[x].cnt;
}
inline bool ident(int x,int f) return tr[f].ch[1]==x;
inline void connect(int x,int f,int s)
{
    tr[f].ch[s]=x;
    tr[x].fa=f;
}
void rot(int x)
{
    int f=tr[x].fa,ff=tr[f].fa,k=ident(x,f);
    connect(tr[x].ch[k^1],f,k);
    connect(x,ff,ident(f,ff));
    connect(f,x,k^1);
    update(f),update(x);
}
void splaying(int x,int top)
{
    if(!top) root=x;
    while(tr[x].fa!=top)
    {
        int f=tr[x].fa,ff=tr[f].fa;
        if(ff!=top) ident(f,ff)^ident(x,f)?rot(x):rot(f);
        rot(x);
    }
}
void newnode(int &now,int fa,int val)
{
    tr[now=++cnt].val=val;
    tr[now].fa=fa;
    tr[now].si=tr[now].cnt=1;
}
void ins(int &now,int fa, int k, int val)
{
    int gg = tr[tr[now].ch[0]].si + tr[now].cnt;
    if(!now) newnode(now,fa,val),splaying(now,0);
    else if(k>gg) ins(tr[now].ch[1],now, k-gg, val);
    else if(k<=gg) ins(tr[now].ch[0],now, k, val);
}
bool _flag = 1;
int cntt = 0;
int n;
void dfs(int cur)
{
    if (cur == 0) return;
    dfs(tr[cur].ch[0]);
    printf(" %d", tr[cur].val);
    dfs(tr[cur].ch[1]);
}
struct node
{
    int h;
    int k;
}q[N];
bool cmp(node a, node b)
{
    if (a.h != b.h) return a.h > b.h;
    return min(a.k, n - a.k) > min(b.k, n - b.k);
}
int main()
{
    int t;
    scanf("%d", &t);
    int t0 = 1;
    while(t--)
    {
        scanf("%d", &n);
        for (int i = 0; i <= n * 2; i++)
        {
            tr[i].ch[0] = tr[i].ch[1] = tr[i].fa = tr[i].si = tr[i].val = tr[i].cnt = 0;
        }
        cnt = 0, root = 0;
        for (int i = 0; i < n; i++)
            scanf("%d%d", &q[i].h, &q[i].k);
        sort(q, q+n, cmp);
        printf("Case #%d:", t0++);
        bool flag = 0;
        for (int i = 0; i < n; i++)
        {
            int kk = q[i].k;
            if (kk > i)
            {
                puts(" impossible");
                flag = 1;
                break;
            }
            int hh = min(kk, i-kk) + 1;
            ins(root, 0, hh, q[i].h);
        }
        if (flag) continue;
        else
        {
            dfs(root);
            printf("\n");
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值