码迷,mamicode.com
首页 > 其他好文 > 详细

vj线段树专题

时间:2019-02-10 17:46:51      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:rom   uil   结束   range   敌兵布阵   build   turn   hat   查询   

vj线段树专题题解

单点更新模板

void build(int x,int l,int r){//sum[x]控制l-r区域
    if(l==r){Sum[x]=num[l];return ;}
    int mid=l+((r-l)>>1);
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    Sum[x]=Sum[x<<1]+Sum[x<<1|1];
}
void add(int a,int b,int l,int r,int x){//num[a]+=b,Sum[x] x=1 单点a增加b
    if(l==r&&a==l){Sum[x]+=b;return ;}
    int mid=l+((r-l)>>1);
    if(a<=mid) add(a,b,l,mid,x<<1);//这里条件判断只和a有关,num[a]
    else add(a,b,mid+1,r,x<<1|1);
    Sum[x]=Sum[x<<1]+Sum[x<<1|1];
}
int query(int a,int b,int l,int r,int x){//range[a,b] query from x 查询区域a-b之间信息
    if(a<=l&&r<=b) return Sum[x];
    int mid=l+((r-l)>>1);
    if(b<=mid) return query(a,b,l,mid,x<<1);//这里和a,b都有关
    if(a>mid) return query(a,b,mid+1,r,x<<1|1);
    return query(a,b,l,mid,x<<1)+query(a,b,mid+1,r,x<<1|1);
}

区间更新模板

void build(int x,int l,int r){
    if(l==r){Sum[x]=nums[l];return;}
    int mid=l+((r-l)>>1);
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    Sum[x]=Sum[x<<1]+Sum[x<<1|1];
}
void pushDown(int x,int len){//len是lazy[p] 管辖的长度
    if(lazy[x]){//先下放到下面,然后讲lazy[]置0
        Sum[x<<1]+=(long long)lazy[x]*(len-((len)>>1));
        Sum[x<<1|1]+=(long long)lazy[x]*(len>>1);
        lazy[x<<1]+=lazy[x];//+=不是=
        lazy[x<<1|1]+=lazy[x];
        lazy[x]=0;
    }
}
void add(int x,int a,int b,int c,int l,int r){
    if(a<=l&&r<=b){//如果要更新的区间覆盖了当控制的区间,设置lazy标记后结束
        lazy[x]+=c;
        Sum[x]+=(long long)c*(r-l+1);
        return ;
    }
    pushDown(x,r-l+1);//否则检查是否由lazy标记,pushDown
    int mid=l+((r-l)>>1);
    if(a<=mid) add(x<<1,a,b,c,l,mid);
    if(b>mid) add(x<<1|1,a,b,c,mid+1,r);
    Sum[x]=Sum[x<<1]+Sum[x<<1|1];
}
long long query(int x,int a,int b,int l,int r){
    if(a<=l&&r<=b){return Sum[x];}
    pushDown(x,r-l+1);
    int mid=l+((r-l)>>1);
    if(b<=mid) return query(x<<1,a,b,l,mid);
    if(a>mid) return query(x<<1|1,a,b,mid+1,r);
    return query(x<<1,a,b,l,mid)+query(x<<1|1,a,b,mid+1,r);
}

题解

a_HDU1166 A - 敌兵布阵

简单的单点更新,动态查询(询问次数很多),是模板题;
每个营地代表一个点,每次查询或更新

代码(略)

B - I Hate It HDU - 1754

代码略

C - A Simple Problem with Integers

区间更新的模板题(lazy标记)

代码略

vj线段树专题

标签:rom   uil   结束   range   敌兵布阵   build   turn   hat   查询   

原文地址:https://www.cnblogs.com/fridayfang/p/10359560.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!