区间求和Java,线段树区间更新,区间求和,最大值,最小值模板

转自http://blog.csdn.net/acmer_ak/article/details/52002537

#include

#include

#include

#include

#include

#define MAXN 100010

#define inf 0x3f3f3f3f

using namespace std;

struct node{

int l,r;//区间[l,r]

int add;//区间的延时标记

int sum;//区间和

int mx; //区间最大值

int mn; //区间最小值

}tree[MAXN<<2];//一定要开到4倍多的空间

void pushup(int index){

tree[index].sum = tree[index<<1].sum+tree[index<<1|1].sum;

tree[index].mx = max(tree[index<<1].mx,tree[index<<1|1].mx);

tree[index].mn = min(tree[index<<1].mn,tree[index<<1|1].mn);

}

void pushdown(int index){

//说明该区间之前更新过

//要想更新该区间下面的子区间,就要把上次更新该区间的值向下更新

if(tree[index].add > 0){

//替换原来的值

/*

tree[index<<1].sum = (tree[index<<1].r-tree[index<<1].l+1)*tree[index].add;

tree[index<<1|1].sum = (tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add;

tree[index<<1].mx = tree[index].add;

tree[index<<1|1].mx = tree[index].add;

tree[index<<1].mn = tree[index].add;

tree[index<<1|1].mn = tree[index].add;

tree[index<<1].add = tree[index].add;

tree[index<<1|1].add = tree[index].add;

tree[index].add = 0;*/

//在原来的值的基础上加上val

tree[index<<1].sum += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].add;

tree[index<<1|1].sum +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add;

tree[index<<1].mx += tree[index].add;

tree[index<<1|1].mx += tree[index].add;

tree[index<<1].mn += tree[index].add;

tree[index<<1|1].mn += tree[index].add;

tree[index<<1].add += tree[index].add;

tree[index<<1|1].add += tree[index].add;

tree[index].add = 0;

}

}

void build(int l,int r,int index){

tree[index].l = l;

tree[index].r = r;

tree[index].add = 0;//刚开始一定要清0

if(l == r){

scanf("%d",&tree[index].sum);

tree[index].mn = tree[index].mx = tree[index].sum;

return ;

}

int mid = (l+r)>>1;

build(l,mid,index<<1);

build(mid+1,r,index<<1|1);

pushup(index);

}

void updata(int l,int r,int index,int val){

if(l <= tree[index].l && r >= tree[index].r){

/*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1

个数,所以区间和 以及 最值为:

*/

/*tree[index].sum = (tree[index].r-tree[index].l+1)*val;

tree[index].mn = val;

tree[index].mx = val;

tree[index].add = val;//延时标记*/

//在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1

//个数,所以区间和 以及 最值为:

tree[index].sum += (tree[index].r-tree[index].l+1)*val;

tree[index].mn += val;

tree[index].mx += val;

tree[index].add += val;//延时标记

return ;

}

pushdown(index);

int mid = (tree[index].l+tree[index].r)>>1;

if(l <= mid){

updata(l,r,index<<1,val);

}

if(r > mid){

updata(l,r,index<<1|1,val);

}

pushup(index);

}

int query(int l,int r,int index){

if(l <= tree[index].l && r >= tree[index].r){

//return tree[index].sum;

return tree[index].mx;

//return tree[index].mn;

}

pushdown(index);

int mid = (tree[index].l+tree[index].r)>>1;

int ans = 0;

int Max = 0;

int Min = inf;

if(l <= mid){

ans += query(l,r,index<<1);

Max = max(query(l,r,index<<1),Max);

Min = min(query(l,r,index<<1),Min);

}

if(r > mid){

ans += query(l,r,index<<1|1);

Max = max(query(l,r,index<<1|1),Max);

Min = min(query(l,r,index<<1|1),Min);

}

//return ans;

return Max;

//return Min;

}

int main()

{

int n,m,q,x,y,z;

while(~scanf("%d%d",&n,&m)){

build(1,n,1);

while(m--){

scanf("%d",&q);

if(q == 1){

cout<

scanf("%d %d",&x,&y);

cout<

}

else{

cout<

scanf("%d %d %d",&x,&y,&z);

updata(x,y,1,z);

for(int i = 1; i <= n; ++i){

printf("a[%d] = %d\n",i,query(i,i,1));

}

}

}

}

return 0;

}

时间: 12-07

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值