主席树

主席树

定义

可持久化的线段树

实现

void mkrt(int &p,int q){
    int tmp = mknode();
    t[tmp] = t[q];
    p = tmp;
}
void pushup(int p){
    t[p].dat = t[t[p].ls].dat+t[t[p].rs].dat;
}
void modify(int &p,int L,int R,int x,int v){
    if(!p)p=mknode();
    if(L==R){
        t[p].dat += v;
        return;
    }
    int mid=L+R>>1;
    if(x<=mid)mkrt(t[p].ls,t[p].ls),modify(t[p].ls,L,mid,x,v);
    else mkrt(t[p].rs,t[p].rs),modify(t[p].rs,mid+1,R,x,v);
    pushup(p);
}
int query(int p,int q,int L,int R,int v){
    if(L==R){//搞清楚访问的是区间还是点 
        return t[p].dat-t[q].dat>=v?L:0;
    }
    int mid=L+R>>1;
    int res=0;
    if(t[t[p].ls].dat-t[t[q].ls].dat>=v)res = query(t[p].ls,t[q].ls,L,mid,v);
    if(res)return res;
    if(t[t[p].rs].dat-t[t[q].rs].dat>=v)res = query(t[p].rs,t[q].rs,mid+1,R,v);
    if(res)return res;
    return res; 
}

参考资料

Oi-wiki

Zhihu

posted @ 2024-02-04 12:39  妖灵梦  阅读(17)  评论(0)    收藏  举报