线段树之区间最大值或区间单点修改和
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;
}

浙公网安备 33010602011771号