HDU 5367动态建立线段树

注意:动态建立线段树pushdown和pushup等操作,一定要先检查节点是否存在
WA了无数次,RE了无数次,之后无奈看了某牛题解

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <map>

using namespace std;
#define MAXN 50010
#define MAXM 1010
#define inf 0x3f3f3f3f
int N, Q;
int T, cur;

struct Node{
    int sum;
    int lsum, rsum;
    int add, lh, rh;
    int ll, rr;
    int ch[2];
    void init( int l, int r ){
        sum = add = lh = rh = ll = rr =ch[0] = ch[1] =  0;
        lsum = rsum = r - l + 1;
    }
};

struct IntervalTree{
    Node node[MAXN * 100];
    void check( int &root, int l, int r ){
        if(root) return ;
        root = ++ cur;
        node[root].init(l, r);
        if(l == 1) node[root].ll = inf;
        if(r == N) node[root].rr = inf;
    }
    void addval(int root, int val){
        node[root].add += val;
        node[root].ll += val;
        node[root].rr += val;
        node[root].lh += val;
        node[root].rh += val;

    }
    void pushdown(int root, int l, int r){
        if(node[root].add){

            int mid = (l + r) >> 1;
            check(node[root].ch[0], l, mid);
            check(node[root].ch[1], mid + 1, r);
            addval(node[root].ch[0], node[root].add);
            addval(node[root].ch[1], node[root].add);
            node[root].add = 0;
        }
    }
    void pushup(int root, int l, int r){
        int mid = (l + r) >> 1;
        check(node[root].ch[0], l, mid);
        check(node[root].ch[1], mid + 1, r);
        int lson = node[root].ch[0], rson = node[root].ch[1];
        node[root].sum = node[lson].sum + node[rson].sum;
        node[root].lsum = node[lson].lsum, node[root].rsum = node[rson].rsum;
        node[root].lh = node[lson].lh, node[root].rh = node[rson].rh;
        node[root].ll = node[lson].ll, node[root].rr = node[rson].rr;

        if(node[lson].rh == node[rson].lh){
            if(node[lson].rh > node[lson].rr && node[rson].lh > node[rson].ll)
                 node[root].sum += node[lson].rsum + node[rson].lsum;

            if(node[lson].rsum == mid - l + 1){
                node[root].lsum += node[rson].lsum;
                node[root].ll = node[rson].ll;
            }
            if(node[rson].lsum == r - mid){
                node[root].rsum += node[lson].rsum;
                node[root].rr = node[lson].rr;
            }

        }

        else {
              if(node[lson].lsum == mid - l + 1) node[root].ll = node[rson].lh;
                if(node[lson].rh > node[rson].lh && node[lson].rh > node[lson].rr)
                   node[root].sum += node[lson].rsum;

              if(node[rson].rsum == r - mid ) node[root].rr = node[lson].rh;
              if(node[rson].lh > node[lson].rh && node[rson].lh > node[rson].ll)
                   node[root].sum += node[rson].lsum;
        }
    }

    void update(int &root, int l, int r, int L, int R, int x){
        check(root, l, r);
        if(L <= l && r <= R){
            addval(root, x);
            return ;
        }
        pushdown(root, l, r);
        int mid = ( l + r ) >> 1;
        if(L <= mid) update(node[root].ch[0], l, mid, L, R, x);
        if(R > mid) update(node[root].ch[1], mid + 1, r, L, R, x);
        pushup(root, l, r);
    }

}tree;

void solve(){
    T = cur = 0;
    int ans = 0;
    int l, r, val;
    for( int i = 0; i < Q; i++){
        scanf("%d %d %d",&l, &r, &val);
        l ^= ans, r^= ans, val^=ans;
        if(l > r) swap(l, r);
        tree.update(T, 1, N, l, r, val);
        ans = tree.node[1].sum;
        printf("%d\n",ans);
    }
}

int main(){
    int val;

    while(scanf("%d%d%d",&N, &Q, &val) != EOF){
        solve();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值