hdu 5367 线段树动态建树

#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
using namespace std;

const int size=851111;
typedef long long ll;
typedef pair<int,int> pii;

int t,n,q,rr,tot;
int lh[size],lcnt[size],lf[size],lson[size],le[size],lz[size],ans[size],len[size];
int rh[size],rcnt[size],rf[size],rson[size],ri[size];

void init(int p,int l,int r,int h){
    lson[p]=rson[p]=lz[p]=ans[p]=0;
    lh[p]=rh[p]=h;
    lf[p]=rf[p]=0;
    lcnt[p]=rcnt[p]=len[p]=r-l+1;
    le[p]=l;ri[p]=r;
}
void make(int &a,int l,int r,int h){
    if(a==0){
        a=++tot;if(tot>size-10)return ;
        init(a,l,r,h);
    }
}
void up(int p){
    int lp=lson[p],rp=rson[p];
    lcnt[p]=lcnt[lp];lf[p]=lf[lp];
    rcnt[p]=rcnt[rp];rf[p]=rf[rp];
    ans[p]=ans[lp]+ans[rp];
    lh[p]=lh[lp];rh[p]=rh[rp];
    if(lcnt[lp]==len[lp]){
        if(lh[lp]==lh[rp])lcnt[p]+=lcnt[rp],lf[p]=lf[rp];
        else lf[p]=lh[lp]>lh[rp];
    }
    if(rcnt[rp]==len[rp]){
        if(rh[rp]==rh[lp])rcnt[p]+=rcnt[lp],rf[p]=rf[lp];
        else rf[p]=rh[rp]>rh[lp];
    }
    if(rh[lp]>lh[rp]&&rf[lp])ans[p]+=rcnt[lp];
    if(rh[lp]<lh[rp]&&lf[rp])ans[p]+=lcnt[rp];
    if(rh[lp]==lh[rp]&&rf[lp]&&lf[rp])ans[p]+=rcnt[lp]+lcnt[rp];
}
void add(int p,int L,int R,int d){
    if(L==le[p]&&R==ri[p]){
        lz[p]+=d;
        lh[p]+=d;rh[p]+=d;
        return ;
    }
    int mid=(le[p]+ri[p])>>1;
    make(lson[p],le[p],mid,rr);
    make(rson[p],mid+1,ri[p],rr);
    if(lz[p]){
        add(lson[p],le[p],mid,lz[p]);
        add(rson[p],mid+1,ri[p],lz[p]);
        lz[p]=0;
    }
    if(R<=mid)add(lson[p],L,R,d);
    else if(L>mid)add(rson[p],L,R,d);
    else {
        add(lson[p],L,mid,d);
        add(rson[p],mid+1,R,d);
    }
    up(p);
}


int main(){
    while(cin>>n>>q>>rr){
        int aa=0;tot=1;
        init(1,1,n,rr);
        while(q--){
            int a,b,r;
            scanf("%d%d%d",&a,&b,&r);
            a^=aa;b^=aa;r^=aa;
            add(1,a,b,r);
            aa=ans[1];
            printf("%d\n",aa);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值