非常简单好用的线段树板子(包括懒标签log(n)更新区间,区间求和,区间求最大值,区间求最小值)

写了一个线段树的板子,包含了区间的求和,求最值,具体使用方法就是调用那个segmentTree类然后定义对象,调用build tree,然后就可以愉快的使用啦。具体使用步骤可以在main函数使用。

复制粘贴的时候不要忘记把

#define left(x) (x<<1)
#define right(x) ((x<<1)+1)

也粘贴走哦。嘻嘻:)

#include <bits/stdc++.h>
using namespace std;
#define left(x) (x<<1)
#define right(x) ((x<<1)+1)
class segmentTree{
    private:
    int MAXN;
    vector<int> rsq;
    vector<int> rmaxq;
    vector<int> rminq;
    vector<int> lazy;
    const int inf=1e9;
    const int FLAG=-1e9;

public:
segmentTree(int range){ //下标范围 假如是1e5 至少开到1e5+1. 不放心的话可以+10
        MAXN=range;
        rsq.assign(4*MAXN,0);
        rmaxq.assign(4*MAXN,0);
        rminq.assign(4*MAXN,0);
        lazy.assign(8*MAXN,FLAG);        
    }
void build(int root,int l,int r,int ql,int qr,int A[]){ //建树 
    
    if(l>=ql && r<=qr &&l==r){
        rminq[root]=rmaxq[root]=rsq[root]=A[l];
        return ;
    }
    if(l>qr || r<ql)return ;
    int mid=l+(r-l)/2;
    build(left(root),l,mid,ql,qr,A);
    build(right(root),mid+1,r,ql,qr,A);
    rsq[root]=rsq[left(root)]+rsq[right(root)];
    rminq[root]=min(rminq[left(root)],rminq[right(root)]);
    rmaxq[root]=max(rmaxq[left(root)],rmaxq[right(root)]);
}
void  Update(int root ,int l,int r,int ql,int qr,int val){  //区间加值
	if(lazy[root]!=FLAG){
		rsq[root]+=(r-l+1)*lazy[root];
		rmaxq[root]+=lazy[root];
		rminq[root]+=lazy[root];
		if(lazy[left(root)]!=FLAG)lazy[left(root)]+=lazy[root];
		else lazy[left(root)]=lazy[root];
		if(lazy[right(root)]!=FLAG)lazy[right(root)]+=lazy[root];
		else lazy[right(root)]=lazy[root];
		lazy[root]=FLAG;
	}
	if(l>=ql && r<=qr){
		if(lazy[left(root)]!=FLAG)lazy[left(root)]+=val;
		else lazy[left(root)]=val;
		if(lazy[right(root)]!=FLAG)lazy[right(root)]+=val;
		else lazy[right(root)]=val;
		rsq[root]+=(r-l+1)*val;
		rmaxq[root]+=val;
		rminq[root]+=val;
		return ;
	}
	if(l>qr || r<ql)return ;
	int mid=l+(r-l)/2;
	Update(left(root),l,mid,ql,qr,val);
	Update(right(root),mid+1,r,ql,qr,val);
	rsq[root]=rsq[left(root)]+rsq[right(root)];
	rmaxq[root]=max(rmaxq[left(root)],rmaxq[right(root)]);
	rminq[root]=min(rminq[left(root)],rminq[right(root)]);
}
int rsq_query(int root, int l,int r,int ql,int qr){ //区间求和查询
   
	if(lazy[root]!=FLAG){
		rsq[root]+=(r-l+1)*lazy[root];
		rmaxq[root]+=lazy[root];
		rminq[root]+=lazy[root];
		if(lazy[left(root)]!=FLAG)lazy[left(root)]+=lazy[root];
		else lazy[left(root)]=lazy[root];
		if(lazy[right(root)]!=FLAG)lazy[right(root)]+=lazy[root];
		else lazy[right(root)]=lazy[root];
		lazy[root]=FLAG;
	}
	if(l>=ql && r<=qr){
        
		return rsq[root];
	}
	if(l>qr || r<ql)return 0;
	int mid=l+(r-l)/2;
	int lv=rsq_query(left(root),l,mid,ql,qr);
	int rv=rsq_query(right(root),mid+1,r,ql,qr);
	return lv+rv;
}
int rmax_query(int root,int l,int r,int ql,int qr){ //区间最大值查询
	if(lazy[root]!=FLAG){
		rsq[root]+=(r-l+1)*lazy[root];
		rmaxq[root]+=lazy[root];
		rminq[root]+=lazy[root];
		if(lazy[left(root)]!=FLAG)lazy[left(root)]+=lazy[root];
		else lazy[left(root)]=lazy[root];
		if(lazy[right(root)]!=FLAG)lazy[right(root)]+=lazy[root];
		else lazy[right(root)]=lazy[root];
		lazy[root]=FLAG;
	}
	if(l>=ql && r<=qr)return rmaxq[root];
	if(l>qr || r<ql)return -inf;
	int mid=l+(r-l)/2;
	int lv=rmax_query(left(root),l,mid,ql,qr);
	int rv=rmax_query(right(root),mid+1,r,ql,qr);
	return max(lv,rv);
}
int rmin_query(int root ,int l,int r,int ql,int qr){    //区间最小值查询
	if(lazy[root]!=FLAG){
		rsq[root]+=(r-l+1)*lazy[root];
		rmaxq[root]+=lazy[root];
		rminq[root]+=lazy[root];
		if(lazy[left(root)]!=FLAG)lazy[left(root)]+=lazy[root];
		else lazy[left(root)]=lazy[root];
		if(lazy[right(root)]!=FLAG)lazy[right(root)]+=lazy[root];
		else lazy[right(root)]=lazy[root];
		lazy[root]=FLAG;
	}
	if(l>=ql && r<=qr)return rminq[root];
	if(l>qr || r<ql)return inf;
	int mid=l+(r-l)/2;
	int lv=rmin_query(left(root),l,mid,ql,qr);
	int rv=rmin_query(right(root),mid+1,r,ql,qr);
	return min(lv,rv);
}
};
int main(){
    int A[]={1,-1,3,4,5};
    int root=1;
   
    for(int i=0;i<5;i++)cout<<A[i]<<" ";
    cout<<endl;
    const int MAXN=1e6;
    segmentTree st(MAXN+10);
     
    
    st.build(root,0,MAXN,0,sizeof(A)/sizeof(A[0])-1,A);
   
    
     cout<<"A range sum query 0 0"<<endl;
    cout<<st.rsq_query(root,0,MAXN,0,0)<<endl;

    cout<<"A range sum query 0 4"<<endl;
    cout<<st.rsq_query(root,0,MAXN,0,4)<<endl;

    cout<<"A range sum query 3 4"<<endl;
    cout<<st.rsq_query(root,0,MAXN,3,4)<<endl;

    cout<<"A[0]+=5"<<endl;
    st.Update(root,0,MAXN,0,0,5);
    A[0]+=5;
    for(int i=0;i<5;i++)cout<<A[i]<<" ";
    cout<<endl;

    cout<<"A range sum query 0 0"<<endl;
    cout<<st.rsq_query(root,0,MAXN,0,0)<<endl;

    cout<<"A range min query 0 0"<<endl;
    cout<<st.rmin_query(root,0,MAXN,0,0)<<endl;

    cout<<"A range min query 0 4"<<endl;
    cout<<st.rmin_query(root,0,MAXN,0,4)<<endl;
    
    
    cout<<"A range max query 0 0"<<endl;
    cout<<st.rmax_query(root,0,MAXN,0,0)<<endl;

    cout<<"A range max query 1 4"<<endl;
    cout<<st.rmax_query(root,0,MAXN,1,4)<<endl;
    
    cout<<"A all elements plus 1"<<endl;
    st.Update(root,0,MAXN,0,4,1);
    for(int i=0;i<5;i++)cout<<++A[i]<<" ";
    cout<<endl;
    
    cout<<"A range sum query 0 4"<<endl;
    cout<<st.rsq_query(root,0,MAXN,0,4)<<endl;

    cout<<"A range min query 0 4"<<endl;
    cout<<st.rmin_query(root,0,MAXN,0,4)<<endl;


    cout<<"A range max query 0 4"<<endl;
    cout<<st.rmax_query(root,0,MAXN,0,4)<<endl;
	return 0;
}
发布了171 篇原创文章 · 获赞 4 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/FrostMonarch/article/details/103506491