2018-team4-modules-可持久化线段树

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

{{{
struct Node{
    Node *ch[2];
    ll mx,id,lazy;
    void update(){
        mx = max(ch[0]->mx,ch[1]->mx);
        if(mx == ch[0]->mx) id = ch[0]->id;
        if(mx == ch[1]->mx) id = ch[1]->id;
        mx += lazy;
    }
}*null,*root[maxn],*it,mem[maxn*50];
inline void init(){
    it = mem;null = it++;
    null->ch[0] = null->ch[1] = null;
    null->mx = null->id = 0;
    root[0] = null;
}
Node* insert(Node *rt,ll l,ll r,ll L,ll R,ll val){
    Node *p = it++;*p = *rt;
    if(L == R && l == r){
        p->id = l;
    }
    if(L <= l && r <= R){
        p->lazy += val;
        p->mx += val;
        return p;
    }
    ll mid = l+r >> 1;
    if(L <= mid) p->ch[0] = insert(p->ch[0],l,mid,L,R,val);
    if(R >  mid) p->ch[1] = insert(p->ch[1],mid+1,r,L,R,val);
    p->update();return p;
}

typedef pair<ll,ll> pa;
inline pa query(Node *p,ll l,ll r,ll L,ll R){
    if(L <= l && r <= R){
        return make_pair(p->mx,p->id);
    }
    ll mid = l+r >> 1;pa x,y;
    if(R <= mid){
        x = query(p->ch[0],l,mid,L,R);
        x.first += p->lazy;
        return x;
    }
    if(L >  mid){
        y = query(p->ch[1],mid+1,r,L,R);
        y.first += p->lazy;
        return y;
    }
    x = query(p->ch[0],l,mid,L,R);
    y = query(p->ch[1],mid+1,r,L,R);
    x.first += p->lazy;y.first+=p->lazy;
    if(x.first > y.first) return x;
    else return y;
}
}}}
struct Node{
    Node *ch[2];
    ll mx,id,lazy;
    void update(){
        mx = max(ch[0]->mx,ch[1]->mx);
        if(mx == ch[0]->mx) id = ch[0]->id;
        if(mx == ch[1]->mx) id = ch[1]->id;
        mx += lazy;
    }
}*null,*root[maxn],*it,mem[maxn*50];
inline void init(){
    it = mem;null = it++;
    null->ch[0] = null->ch[1] = null;
    null->mx = null->id = 0;
    root[0] = null;
}
Node* insert(Node *rt,ll l,ll r,ll L,ll R,ll val){
    Node *p = it++;*p = *rt;
    if(L == R && l == r){
        p->id = l;
    }
    if(L <= l && r <= R){
        p->lazy += val;
        p->mx += val;
        return p;
    }
    ll mid = l+r >> 1;
    if(L <= mid) p->ch[0] = insert(p->ch[0],l,mid,L,R,val);
    if(R >  mid) p->ch[1] = insert(p->ch[1],mid+1,r,L,R,val);
    p->update();return p;
}
typedef pair<ll,ll> pa;
inline pa query(Node *p,ll l,ll r,ll L,ll R){
    if(L <= l && r <= R){
        return make_pair(p->mx,p->id);
    }
    ll mid = l+r >> 1;pa x,y;
    if(R <= mid){
        x = query(p->ch[0],l,mid,L,R);
        x.first += p->lazy;
        return x;
    }
    if(L >  mid){
        y = query(p->ch[1],mid+1,r,L,R);
        y.first += p->lazy;
        return y;
    }
    x = query(p->ch[0],l,mid,L,R);
    y = query(p->ch[1],mid+1,r,L,R);
    x.first += p->lazy;y.first+=p->lazy;
    if(x.first > y.first) return x;
    else return y;
}