HDU1754 Splay 区间维护

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <string>
#include <vector>

using namespace std;

#define REP(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template<typename T> inline bool chkmin(T &a, const T &b){ return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b){ return a < b ? a = b, 1 : 0; }

typedef long long LL;

const int dmax = 300100, oo = 0x3f3f3f3f;

int n, m;

#define L ch[0]
#define R ch[1]

struct node
{
    int x, val, max, size;
    node *f, *ch[2];
    node()
    {
        x = val = max = size = 0;
        f = L = R = NULL;
    }
};

node *Null = new node;

inline node *new_node(int k, int val)
{
    node *tmp = new node;
    tmp->x = k;
    tmp->size = 1;
    tmp->val = tmp->max = val;
    tmp->f = tmp->L = tmp->R = Null;
    return tmp;
}

struct Splay
{
    node *root;
    node *c[dmax];
    inline bool is_root(node *t){ return t == root; }
    inline int Max(node *t){ return t == Null ? -oo : t->max; }
    inline int size(node *t){ return t == Null ? 0 : t->size; }
    inline void push_up(node *t)
    {
        int T = max(Max(t->L), Max(t->R));
        t->max = max(T, t->val);
        t->size = size(t->L) + size(t->R) + 1;
    }
    inline void rotate(node *x)
    {
        node *y = x->f;
        if (is_root(y))
            root = x;
        else{
            if (y == y->f->L)
                y->f->L = x;
            else y->f->R = x;
        }
        x->f = y->f;
        int k = x == y->R;
        y->ch[k] = x->ch[!k];
        x->ch[!k]->f = y;
        x->ch[!k] = y;
        y->f = x;
        push_up(y);
        push_up(x);
    }
    inline void splay(node *x, node *t)
    {
        while (x->f != t)
        {
            node *y = x->f;
            if (y->f == t)
                rotate(x);
            else{
                node *z = y->f;
                if (x == z->L->L || x == z->R->R)
                    rotate(y);
                else rotate(x);
                rotate(x);
            }
        }
    }
    inline void push(node *t, int k, int val)
    {
        int T = k >= t->x;
        c[k] = t->ch[T] = new_node(k, val);
        t->ch[T]->f = t;
        t = t->ch[T];
        node *tmp = t;
        while (tmp != Null)
        {
            push_up(tmp);
            tmp = tmp->f;
        }
        splay(t, Null);
    }
    void insert(int k, int val, node *t)
    {
        int T = k >= t->x;
        if (t->ch[T] != Null)
            insert(k, val, t->ch[T]);
        else push(t, k, val);
    }
    inline void access(int x, int y)
    {
        splay(c[x - 1], Null);
        splay(c[y + 1], root);
    }
    inline int query(int x, int y)
    {
        access(x, y);
        return c[y + 1]->L->max;
    }
    void update(int k, int s, node *t)
    {
        if (k == t->x)
        {
            t->val = s;
            push_up(t);
        }
        int T = k > t->x;
        if (t->ch[T] != Null)
            update(k, s, t->ch[T]);
        push_up(t);
    }
    void dfs(node *t)
    {
        if (t == Null || t == NULL) return;
        dfs(t->L);
        dfs(t->R);
        delete t;
    }
}t;

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    while (scanf("%d%d", &n, &m) != EOF)
    {

        t.dfs(t.root);
        t.root = t.c[0] = new_node(0, -oo);
        REP(i, 1, n)
        {
            int k;
            scanf("%d", &k);
            t.insert(i, k, t.root);
        }
        t.insert(n + 1, -oo, t.root);
        getchar();
        while (m--)
        {
            int c = getchar(), x, y;
            scanf("%d%d", &x, &y);
            if (c == 'Q')
                printf("%d\n", t.query(x, y));
            else t.update(x, y, t.root);
            getchar();
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值