线段树模板

//区间替换,区间求和
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
#define MAXN 100
#define middle (left+right)>>1
#define leftSon left,(left+right)>>1,root<<1
#define rightSon ((left+right)>>1)+1,right,root<<1|1
int n,sum[MAXN<<2],lazy[MAXN<<2];
void PushUp(int root){
	sum[root]=sum[root<<1]+sum[root<<1|1];
}
void PushDown(int root,int len){
	if(lazy[root]){
		sum[root<<1]=(len-(len>>1))*lazy[root];
		sum[root<<1|1=(len>>1)*lazy[root];
		lazy[root<<1]=lazy[root];
		lazy[root<<1|1]=lazy[root];
		lazy[root]=0;
	}
}
void BuildTree(int left,int right,int root){
	if(left==right){
		cin>>sum[root];
		return;
	}
	BuildTree(leftSon);
	BuildTree(rightSon);
	PushUp(root);
}
int Sum(int l,int r,int left,int right,int root){
	if(l<=left&&r>=right){
		return sum[root];
	}
	PushDown(root,right-left+1);
	int re=0;
	if(l<=middle)
		re+=Sum(l,r,leftSon);
	if(r>middle)
		re+=Sum(l,r,rightSon);
	return re;
}
void Update(int l,int r,int num,int left,int right,int root){
	if(l<=left&&r>=right){
		sum[root]=(right-left+1)*num;
		lazy[root]=num;
		return;
	}
	PushDown(root,right-left+1);
	if(l<=middle)
		Update(l,r,num,leftSon);
	if(r>middle)
		Update(l,r,num,rightSon);
	PushUp(root);
}
int main(){
	int l,r,loc,num;
	char Oper[10];
	cin>>n;
	BuildTree(1,n,1);
	while(scanf("%s",Oper)!=EOF){
		if(Oper[0]=='Q'){//区间求和
			cin>>l>>r;
			cout<<Sum(l,r,1,n,1)<<endl;
		}
		else if(Oper[0]=='U'){//区间替换
			cin>>l>>r>>num;
			Update(l,r,num,1,n,1);
		}
	}
	return 0;
}


//单点替换,单点增减,区间求和,区间最值
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
#define MAXN 100
#define INF 0X3F3F3F3F
#define middle (left+right)>>1
#define leftSon left,(left+right)>>1,root<<1
#define rightSon (left+right)>>1+1,right,root<<1|1
int n,sum[MAXN<<2],MIN[MAXN<<2],MAX[MAXN<<2];
void PushUp(int root){
	sum[root]=sum[root>>1]+sum[root>>1|1];
	MIN[root]=min(MIN[root>>1],MIN[root>>1|1]);
	MAX[root]=max(MAX[root>>1],MAX[root>>1|1]);
}
void BuildTree(int left,int right,int root){
	if(left==right){
		cin>>sum[root];
		MIN[root]=sum[root];
		MAX[root]=sum[root];
		return;
	}
	BuildTree(leftSon);
	BuildTree(rightSon);
	PushUp(root);
}
int FindMax(int l,int r,int left,int right,int root){
	if(l<=left&&r>=right){
		return MAX[root];
	}
	int M=-1;
	if(l<=middle)
		M=max(M,FindMax(l,r,leftSon));
	if(r>middle)
		M=max(M,FindMax(l,r,rightSon));
	return M;
}
int FindMin(int l,int r,int left,int right,int root){
	if(l<=left&&r>=right){
		return MIN[root];
	}
	int M=INF;
	if(l<=middle)
		M=min(M,FindMin(l,r,leftSon));
	if(r>middle)
		M=min(M,FindMin(l,r,rightSon));
	return M;
}
int FindSum(int l,int r,int left,int right,int root){
	if(l<=left&&r>=right){
		return sum[root];
	}
	int re=0;
	if(l<=middle)
		re+=FindSum(l,r,leftSon);
	if(r>middle)
		re+=FindSum(l,r,rightSon);
	return re;
}
void Update(int loc,int num,int left,int right,int root){
	if(left==right){
		sum[root]=num;
		MAX[root]=num;
		MIN[root]=num;
		return;
	}
	if(loc<=middle)
		Update(loc,num,leftSon);
	if(loc>middle)
		Update(loc,num,rightSon);
	PushUp(root);
}
void Increase(int loc,int num,int left,int right,int root){
	if(left==right){
		sum[root]+=num;
		MAX[root]+=num;
		MIN[root]+=num;
		return;
	}
	if(loc<=middle)
		Increase(loc,num,leftSon);
	if(loc>middle)
		Increase(loc,num,rightSon);
	PushUp(root);
}
int main(){
	int l,r,loc,num;
	char Oper[10];
	cin>>n;
	BuildTree(1,n,1);
	while(scanf("%s",Oper)!=EOF){
		if(Oper[0]=='Q'){//区间求最大
			cin>>l>>r;
			cout<<FindMax(l,r,1,n,1)<<endl;
		}
		else if(Oper[0]=='M'){//区间求最小
			cin>>l>>r;
			cout<<FindMin(l,r,1,n,1);
		}
		else if(Oper[0]=='H'){//区间求和
			cin>>l>>r;
			cout<<FindSum(l,r,1,n,1)<<endl;
		}
		else if(Oper[0]=='U'){//单点替换
			cin>>loc>>num;
			Update(loc,num,1,n,1);
		}
		else if(Oper[0]=='E'){//单点增加
			cin>>loc>>num;
			Increase(loc,num,1,n,1);
		}
		else if(Oper[0]=='S'){//单点减少
			cin>>loc>>num;
			Increase(loc,-num,1,n,1);
		}
	}
	return 0;
}


//区间增减,区间求和
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
#define MAXN 100005
#define middle (left+right)>>1
#define leftSon left,(left+right)>>1,root<<1
#define rightSon ((left+right)>>1)+1,right,root<<1|1
int n;
long long sum[MAXN<<2],lazy[MAXN<<2];
void PushUp(int root){
	sum[root]=sum[root<<1]+sum[root<<1|1];
}
void PushDown(int root,int len){
	if(lazy[root]){
		sum[root<<1]+=(len-(len>>1))*lazy[root];
		sum[root<<1|1]+=(len>>1)*lazy[root];
		lazy[root<<1]+=lazy[root];
		lazy[root<<1|1]+=lazy[root];
		lazy[root]=0;
	}
}
void BuildTree(int left,int right,int root){
	if(left==right){
		scanf("%lld",&sum[root]);
		return;
	}
	BuildTree(leftSon);
	BuildTree(rightSon);
	PushUp(root);
}
long long Sum(int l,int r,int left,int right,int root){
	if(l<=left&&r>=right){
		return sum[root];
	}
	PushDown(root,right-left+1);
	long long re=0;
	if(l<=middle)
		re+=Sum(l,r,leftSon);
	if(r>middle)
		re+=Sum(l,r,rightSon);
	return re;
}
void Update(int l,int r,int num,int left,int right,int root){
	if(l<=left&&r>=right){
		sum[root]+=(right-left+1)*num;
		lazy[root]+=num;
		return;
	}
	PushDown(root,right-left+1);
	if(l<=middle)
		Update(l,r,num,leftSon);
	if(r>middle)
		Update(l,r,num,rightSon);
	PushUp(root);
}
int main(){
	int m,l,r,num;
	char Oper[10];
	cin>>n>>m;
	BuildTree(1,n,1);
	for(int i=1;i<=m;i++){
		scanf("%s",Oper);
		if(Oper[0]=='Q'){
			scanf("%d%d",&l,&r);
			printf("%lld\n",Sum(l,r,1,n,1));
		}
		else{
			scanf("%d%d%d",&l,&r,&num);
			Update(l,r,num,1,n,1);
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值