写了一个线段树的板子,包含了区间的求和,求最值,具体使用方法就是调用那个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;
}