操作说明:
- segtree<T>tree(len) =>创建一个内部元素类型为T、区间为1~len的线段树tree
- tree.build(l,r) =>以[l,r]区间建立线段树
- tree.update(l,r,val,1,len) =>区间[l,r]所有元素加上val
- tree.query(l,r,1,len) =>计算区间[l,r]的元素和
#include <iostream> #include <string> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <deque> #include <map> #define range(i,a,b) for(auto i=a;i<=b;++i) #define LL long long #define itrange(i,a,b) for(auto i=a;i!=b;++i) #define rerange(i,a,b) for(auto i=a;i>=b;--i) #define fill(arr,tmp) memset(arr,tmp,sizeof(arr)) using namespace std; template <class T> class segtree{ private: T* add,*sum; void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void pushdown(int rt,int m){ if(add[rt]){ add[rt<<1]+=add[rt]; add[rt<<1|1]+=add[rt]; sum[rt<<1]+=add[rt]*(m-(m>>1)); sum[rt<<1|1]+=add[rt]*(m>>1); add[rt]=0; } } public: explicit segtree(int len=int(1e5+5)){ add=new T[len<<2]; sum=new T[len<<2]; fill(add,0);fill(sum,0); } void build(int l,int r,int rt=1){ add[rt]=0; if(l==r){ sum[rt]=0; return; } int m=(l+r)>>1; build(l,m,rt<<1); build(m+1,r,rt<<1|1); pushup(rt); } void update(int L,int R,T c,int l,int r,int rt=1){ if(L<=l&&r<=R){ add[rt]+=c; sum[rt]+=c*(r-l+1); return; } pushdown(rt,r-l+1); int m=(l+r)>>1; if(L<=m)update(L,R,c,l,m,rt<<1); if(m<R)update(L,R,c,m+1,r,rt<<1|1); pushup(rt); } T query(int L,int R,int l,int r,int rt=1){ if(L<=l&&r<=R)return sum[rt]; pushdown(rt,r-l+1); int m=(l+r)>>1; T ret=0; if(L<=m)ret+=query(L,R,l,m,rt<<1); if(m<R)ret+=query(L,R,m+1,r,rt<<1|1); return ret; } }; int main() { segtree<int>tree(10); tree.build(1,10); tree.update(1,5,1,1,10); cout<<tree.query(1,5,1,10)<<endl; return 0; }