线段树之区间最大值或区间单点修改和

struct NODE{
	int left;
	int right;
	int value;
}node[MAXNODE];
int father[MAX];//left=right即区间长度为0时的点对应的数组下标 
//inline int lb(int p) {
//	return p<<1;
//}
//左儿子 
//inline int rb(int p){
//	return p<<1|1;
//}
 
//右儿子 
void BuildTree(int i,int left,int right){
	node[i].left=left;
	node[i].right=right;
	node[i].value=0;
	if(left==right){//区间长度为0时,结束递归 
		father[left]=i;//能知道某一个点对应的序号,为了更新时从下往上更新 
		return;
	}
	BuildTree(i<<1,left,(right+left)>>1);
	BuildTree((i<<1)+1,((right+left)>>1)+1,right);
}
void Update(int r){//从下往上更新 ,这个点本身已经在函数外更新过 
	if(r==1) return;//更新到顶了
	int fu=r>>1;//求父结点w
	int a=node[fu<<1].value;
	int b=node[(fu<<1)+1] .value;
	//求孩子结点
	//求最大值
	node[fu].value=max(a,b); 
	Update(fu);// 从下往上更新	
}
int Query(int i,int l,int r) //i为区间序号 l,r为区间端点
{ 	
	if(node[i].left==l && node[i].right==r){//查找的区间完全重合 
//如我想找 [1,3]的最大值 如果此时node[i]的区间值就是[1,3]
//就可以直接使用
		return (Max,node[i].value); 
}
	i=i<<1;
	int Max=0;
	if(r<=node[i].right){
		Max=max(Max,query(i,l,r));
	}
	else if(l>node[i].right){
		Max=max(Max,query(i+1,l,r));
	}
	else {
                Max=max(Max,query(i,l,node[i].right));
                Max=max(Max,query(i+1,node[i+1].left,r));
	}
	return Max;
} 

求单点修改区间和
与上面几乎一样 修改部分代码即可
例题洛谷2068

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#define int long long 
using namespace std;
const int MAX=1e5+5;
struct NODE{
	int left;
	int right;
	int value;
	int mid(){
		return (left+right)>>1;
	}
}node[1<<20];
int father[MAX];
void build(int i,int l,int r){
	node[i].left=l;
	node[i].right=r;
	node[i].value=0;
	if(l==r){
		father[l]=i;
		return ;
	}
	int m=node[i].mid();
	build(i<<1,l,m);
	build(i<<1|1,m+1,r);
}
void update(int r){
	if(r==1) return;
	int fu=r>>1;
	node[fu].value=node[fu<<1].value+node[fu<<1|1].value;
	update(fu);
}
int query(int i,int l,int r){
	if(l==node[i].left && r==node[i].right){
		return node[i].value;
	}
	i=i<<1;
	int res=0;
	if(r<=node[i].right){
		res+=query(i,l,r);
	}
	else if(l>node[i].right){
		res+=query(i+1,l,r);
	}
	else {
		res+=query(i,l,node[i].right);
		res+=query(i+1,node[i+1].left,r);
	}
	return res;
}
int n,w;
signed main(){
		  //freopen("testdata.in", "r", stdin);
	cin>>n>>w;
	build(1,1,n);
	string c;
	int a,b;
	while(w--){
		cin>>c>>a>>b;
		if(c[0]=='x'){
			node[father[a]].value+=b;
			update(father[a]);
		}
		else {
			printf("%lld\n",query(1,a,b));
		}
		
	}
  return 0;
}




posted @ 2020-10-28 20:57  一个经常掉线的人  阅读(162)  评论(0)    收藏  举报