HDU 1754 I Hate It (Splay tree和Segment tree)

线段树的模版题,求区间最值和修改一个值,用Splaytree来写更简单!


伸展树code:

#include 
    
    
     
     
#include 
     
     
      
      
using namespace std;

#define lson x->ch[0]
#define rson x->ch[1]
#define ket (root->ch[1]->ch[0])

const int maxn = 222222 + 10;

struct NODE {
    NODE *pre, *ch[2];
    int val, mx, id, sz;

    void up() {
        sz = ch[0]->sz + ch[1]->sz + 1;
        mx = val;
        if(ch[0]->pre)  mx = max(mx, ch[0]->mx);
        if(ch[1]->pre)  mx = max(mx, ch[1]->mx);
    }
};

struct Splaytree {
    int top;
    NODE node[maxn], *null, *root;

    void Rotate(NODE *x, int c) {
        NODE *y = x->pre;
        y->ch[!c] = x->ch[c];
        if(x->ch[c] != null)    x->ch[c]->pre = y;
        x->pre = y->pre;
        if(y->pre != null)  y->pre->ch[ y->pre->ch[1]==y ] = x;
        x->ch[c] = y; y->pre = x;
        y->up();
    }

    void Splay(NODE *x, NODE *go) {
        while(x->pre != go) {
            if(x->pre->pre == go)   Rotate(x, x->pre->ch[0]==x);
            else {
                NODE *y = x->pre, *z = y->pre;
                int f = z->ch[1] == y;
                if(y->ch[f] == x)   Rotate(y, !f);
                else    Rotate(x, f);
                Rotate(x, !f);
            }
        }
        x->up();
        if(go == null)  root = x;
    }

    void RTO(int k, NODE *go) {
        NODE *x = root;
        while(lson->sz != k) {
            if(lson->sz > k)    x = lson;
            else {
                k -= lson->sz + 1;
                x = rson;
            }
        }
        Splay(x, go);
    }

    int a[maxn];

    NODE *newnode(int c, NODE *f) {
        NODE *x = &node[++top];
        x->pre = f; x->id = top;
        x->val = x->mx = c;
        x->sz = 1;
        lson = rson = null;
        return x;
    }

    NODE *build(int l, int r, NODE *f) {
        if(l > r)   return null;
        int mid = (l+r)/2;
        NODE *x = newnode(a[mid], f);
        lson = build(l, mid-1, x);
        rson = build(mid+1, r, x);
        x->up();
        return x;
    }

    void init(int n) {
        null = &node[0];
        null->sz = null->id = null->val = null->mx = 0;
        top = 0;
        root = newnode(-1, null);
        root->ch[1] = newnode(-1, root);
        ket = build(0, n-1, root->ch[1]);
        root->ch[1]->up(); root->up();
    }

    void query(int l, int r) {
        if(l > r)   swap(l, r);
        RTO(l-1, null);
        RTO(r+1, root);
        printf("%d\n", ket->mx);
    }

    void update(int x, int y) {
        RTO(x, null);
        root->val = y;
    }

    void solve() {
        int n, m;
        while(scanf("%d%d", &n, &m) != -1) {
            for(int i = 0;i < n; i++)   scanf("%d", &a[i]);
            init(n);
            while(m--) {
                char op[2]; int x, y;
                scanf("%s%d%d", op, &x, &y);
                if(op[0] == 'Q')    query(x, y);
                else    update(x, y);
            }
        }
    }
}spt;

int main() {
    spt.solve();
    return 0;
}

     
     
    
    

线段树code:

#include 
    
    
     
     
#include 
     
     
      
      
using namespace std;

#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r

const int maxn = 200000+5;

struct Segtree {
    int mx[maxn<<2];
    void build(int rt, int l, int r) {
        if(l == r) {
            scanf("%d", &mx[rt]);
            return ;
        }
        int mid = (l+r)/2;
        build(lson); build(rson);
        up(rt);
    }

    void up(int rt) {
        mx[rt] = max(mx[rt<<1], mx[rt<<1|1]);
    }

    void update(int rt, int l, int r, int x, int v) {
        if(l == r) {
            mx[rt] = v;
            return ;
        }
        int mid = (l+r)/2;
        if(x <= mid)    update(lson, x, v);
        else    update(rson, x, v);
        up(rt);
    }

    int query(int rt, int l, int r, int L, int R) {
        if(L <= l && R >= r)
            return mx[rt];
        int mid = (l+r)/2;
        int ret = 0;
        if(L <= mid)    ret = max(ret, query(lson, L, R));
        if(R >mid)  ret = max(ret, query(rson, L, R));
        return ret;
    }
}st;

int main() {
    int n, m, x, y;
    char op[2];
    while(scanf("%d%d", &n, &m) == 2) {
        st.build(1, 1, n);
        while(m--) {
            scanf("%s%d%d", op, &x, &y);
            if(op[0] == 'Q')    printf("%d\n", st.query(1, 1, n, x, y));
            else    st.update(1, 1, n, x, y);
        }
    }
    return 0;
}

     
     
    
    

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值