hdu 1754 I Hate It (Splay)

           点修改,区间查询。可以用线段树,也可以用Spaly树。用来练习Spaly树吧。。学习Splay树的话推荐一个博客:点击打开链接

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;

const int N = 201000;
const int INF = 0x3f3f3f3f;
int pre[N], key[N], ch[N][2], root, res[N];
//分别表示父结点,键值,左右孩子(0左1右),根结点

//新建一个结点
void NewNode(int r, int val)
{
    pre[r] = r - 1;
    res[r] = key[r] = val;
    ch[r][0] = ch[r][1] = 0;
    ch[r - 1][1] = r;
}

void Push_Up(int x)
{
    res[x] = max(res[ch[x][0]], res[ch[x][1]]);
    res[x] = max(res[x], key[x]);
}
//旋转,kind为1是右旋,为0是左旋
void Rotate(int x, int kind)
{
    int y = pre[x];
    ch[y][!kind] = ch[x][kind];
    pre[ch[x][kind]] = y;
    if(pre[y])
        ch[pre[y]][ch[pre[y]][1] == y] = x;
    pre[x] = pre[y];
    ch[x][kind] = y;
    pre[y] = x;
    Push_Up(y);
}
//Splay调整,将结点r调整到goal下面
void Splay(int r, int goal)
{
    while(pre[r] != goal)
    {
        if(pre[pre[r]] == goal) Rotate(r, ch[pre[r]][0] == r);
        else
        {
            int y = pre[r];
            int kind = ch[pre[y]][0] == y;
            if(ch[y][kind] == r)
            {
                Rotate(r, !kind);
                Rotate(r, kind);
            }
            else
            {
                Rotate(y, kind);
                Rotate(r, kind);
            }
        }
    }
    if(goal == 0) root = r;
}

void Update(int r, int val)
{
    Splay(r, 0);
    key[r] = val;
    Push_Up(r);
}

int Query(int l, int r)
{
    Splay(l - 1, 0);
    Splay(r + 1, l - 1);
    return res[ch[r + 1][0]];
}

int main()
{
    int n, m, v, q;
    char c[2];
    while(scanf("%d%d", &n, &m) != EOF)
    {
        NewNode(1, -INF);
        for(int i = 1; i <= n; i ++)
        {
            scanf("%d", &v);
            NewNode(i + 1, v);
        }
        NewNode(n + 2, -INF);
        for(int i = n + 2; i; i --)
            Push_Up(i);
        root = 1;
        for(int i = 0; i < m; i ++)
        {
            scanf("%s%d%d", c, &q, &v);
            if(c[0] == 'Q')
                printf("%d\n", Query(q + 1, v + 1));
            else Update(q + 1, v);
        }
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值