线段树 区间更新

给大家推荐两个博客:

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

http://blog.csdn.net/zip_fan/article/details/46775633

之前写的是单点更新,区间更新的板子写完还是不怎么懂

有些地方可能写的不一定对,有错的希望指出

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>

using namespace std;
const int INF=1<<29;
int max_tree[300000];
int min_tree[300000];
int sum_tree[300000]; 
int lazy[300000]={0};
int a[300000];
int n=12;
void build(int node,int begin,int end){//建树 
	if(begin==end) min_tree[node]=a[begin],max_tree[node]=a[begin],sum_tree[node]=a[begin];
	else{
		build(2*node,begin,(begin+end)/2);
		
		build(2*node+1,(begin+end)/2+1,end);
		
		max_tree[node]=max(max_tree[2*node],max_tree[2*node+1]);
		
		min_tree[node]=min(min_tree[2*node],min_tree[2*node+1]);
		
		sum_tree[node]=sum_tree[2*node]+sum_tree[2*node+1];
	}
}
void pushdown(int node,int m){
	if(lazy[node]!=0){
		// 将区间内的数变为num,lazy[node]=num 
		min_tree[2*node]=lazy[node];
		max_tree[2*node]=lazy[node];
		sum_tree[2*node]=(m-(m/2))*lazy[node];
		
		min_tree[2*node+1]=lazy[node];
		max_tree[2*node+1]=lazy[node];
		sum_tree[2*node+1]=(m/2)*lazy[node];
		lazy[node*2]=lazy[node];  
        lazy[node*2+1]=lazy[node];  
        lazy[node]=0; 
		// 
		/*min_tree[2*node]+=lazy[node];
		max_tree[2*node]+=lazy[node];
		sum_tree[2*node]+=(m-(m/2))*lazy[node];
		
		min_tree[2*node+1]+=lazy[node];
		max_tree[2*node+1]+=lazy[node];
		sum_tree[2*node+1]+=(m/2)*lazy[node];
		lazy[node*2]+=lazy[node];  
        lazy[node*2+1]+=lazy[node];  
        lazy[node]=0; */ 
	}
}
int findmin(int node,int begin,int end,int z,int y){//找到z--y的最小值 
	int p1=INF,p2=INF;
	if(begin>=z&&end<=y) return min_tree[node];
	int fz=(begin + end) / 2;
	pushdown(node,end-begin+1);
	if(z<=fz)
	p1=findmin(2*node,begin,fz, z, y) ;
	if(y>fz)
	p2=findmin(2*node+1,fz+1,end,z,y);
	return min(p1,p2);
}
int findmax(int node,int begin,int end,int z,int y){//找到z--y的最大值 
	int p1=-INF,p2=-INF;
	if(begin>=z&&end<=y) return max_tree[node];
	int fz=(begin + end) / 2;
	pushdown(node,end-begin+1);
	if(z<=fz)
	p1=findmax(2*node,begin,fz, z, y) ;
	if(y>fz)
	p2=findmax(2*node+1,fz+1,end,z,y);
	return max(p1,p2);
}
int getsum(int node,int begin,int end,int z,int y){//求z--y的和 
	if(begin>=z&&end<=y) return sum_tree[node];
	int fz=(begin + end) / 2;
	pushdown(node,end-begin+1);
	int sum=0;
	if(z<=fz) sum+=getsum(2*node,begin,fz,z,y);
	if(y>fz) sum+=getsum(2*node+1,fz+1,end,z,y);
	return sum;
}
void updata(int node,int begin,int end,int z,int y,int num){
	if(begin>=z&&end<=y){
		//将z--y更新成num 
		min_tree[node]=num;
		max_tree[node]=num;
		sum_tree[node]=num*(end-begin+1);
		lazy[node]=num;
		
		/*min_tree[node]+=num;
		max_tree[node]+=num;
		sum_tree[node]+=num*(end-begin+1);
		lazy[node]+=num;*/ 
		return;
	}
	pushdown(node,end-begin+1);
	int fz=(begin+end)/2;
	if(z<=fz) updata(2*node,begin,fz,z,y,num);
	if(y>fz) updata(2*node+1,fz+1,end,z,y,num);
	min_tree[node]=min(min_tree[2*node],min_tree[2*node+1]);
	max_tree[node]=max(max_tree[2*node],max_tree[2*node+1]);
	sum_tree[node]=sum_tree[2*node]+sum_tree[2*node+1];
}
int main(){
	a[1]=2,a[2]=3,a[3]=8,a[4]=1,a[5]=5,a[6]=7;
	a[7]=2,a[8]=3,a[9]=8,a[10]=1,a[11]=5,a[12]=7;
	// 2 3 8 1 5 7 2 3 8 1 5 7 
	build(1,1,n);
	
	
	
	/*
	 更新a[3]=0,a[4]=10 
	*/
	cout<<"更新2--5为10"<<endl; 
	updata(1,1,n,2,5,10);
	cout<<"2--5区间最小值:"<<findmin(1,1,n,2,5)<<endl;
	cout<<"2--5区间最大值:"<<findmax(1,1,n,2,5)<<endl;
	cout<<"2--10区间和 :"<<getsum(1,1,n,2,10)<<endl;
	
	cout<<"1--12区间和 :"<<getsum(1,1,n,1,12)<<endl;
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值