#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int Tree[maxn<<2],lazy[maxn<<2];
int ans=0;
void push_up(int root){
Tree[root]=Tree[root<<1]+Tree[(root<<1)|1];//这里只是求和,还可以变为其他的形式max或者min,根据情况而定
}
void push_down(int root,int L,int R){
if(L>R)return;//如果区间不存在
if(lazy[root])return;//如果没有标记
if(!lazy[root]){//如果标记了,那么久下放
lazy[root<<1]=lazy[root];
lazy[(root<<1)|1]=lazy[root];
//改变root节点的孩子利用lazy
//因为lazy通常只是Tree对应的倍数关系
int mid=(L+R)/2;
Tree[root<<1]=(mid-L+1)*lazy[root<<1];
Tree[(root<<1)|1]=(R-mid)*lazy[(root<<1)|1];
//取消标记
lazy[root]=0;
}
}
void Build(int root,int L,int R){
if(L==R){
scanf("%d",Tree+root);
return;
}else{
int mid=(L+R)/2;
Build(root<<1,L,mid);
Build((root<<1)|1,mid+1,R);
push_up(root);
}
}
//区间和
void Query(int root,int L,int R,int l,int r){//求l,r的区间和L,R为系统区间,也就是线段树的逻辑区间
if(l>r||L>R)return;//因为这里根本【4,3】根本不会有这个区间
if(l<=L&&R<=r){
//操作求和或者其他的
ans+=Tree[root];//注意是这点的节点
return ;
}
int mid=(L+R)/2;
if(l<=mid) Query(root<<1,L,mid,l,r);
if(r>mid) Query((root<<1)|1,mid+1,R,l,r);
}
//单点更新
void UpdataPoint(int root,int L,int R,int x,int val){
if(L==R){
//操作
Tree[root]+=val;//这里是改变量为val
return;
}
int mid=(L+R)/2;
if(x<=mid) UpdataPoint(root<<1,L,mid,x,val);
if(x>mid) UpdataPoint((root<<1)|1,mid+1,R,x,val);
push_up(root);
}
//区间更新
void UpdataSection(int root,int L,int R,int l,int r,int val){
if(l>r||L>R)return;
if(l<=L&&R<=r){
Tree[root]=(R-L+1)*val;
lazy[root]=val;
return;
}
push_down(root,L,R);
int mid=(L+R)/2;
if(l<=mid) UpdataSection(root<<1,L,mid,l,r,val);//注意这里是l,r是没有变的
if(r>mid) UpdataSection((root<<1)|1,mid+1,R,l,r,val);
push_up(root);
}
int main(){
return 0;
}
线段树基础操作(自己总结的)
最新推荐文章于 2022-07-27 21:31:39 发布