线段树模板
线段树模板。
typedef long long lli;
template<class T=int,int Size=1000001>
class segment_tree
{
typedef long long lli;
int n;
lli *tr,*tag;
allocator<lli> fd;
void init();
void build(int now,int l,int r,const T (&arr)[Size]);
lli query(int now,int gl,int gr,int l,int r);
void update(int now,int gl,int gr,int l,int r,int k);
void push_down(int now,int l,int r);
void modify(int now,int l,int r,int k)
{
tag[now]+=k;
tr[now]+=k*(r-l+1);
}
void push_up(int now)
{
tr[now]=tr[now<<1]+tr[now<<1|1];
}
public:
segment_tree(const int& _n):n(_n){init();}
segment_tree(const int& _n,const T (&arr)[Size]):n(_n){init();build(1,1,n,arr);}
~segment_tree();
void build(const T (&arr)[Size]){build(1,1,n,arr);}
lli query(int l,int r){return query(1,l,r,1,n);}
void update(int l,int r,int k){update(1,l,r,1,n,k);}
lli query(int id){return query(id,id);}
void update(int id,int k){update(id,id,k);}
};
template<class T,int Size>
void segment_tree<T,Size>::init()
{
tr=fd.allocate(Size<<2);
tag=fd.allocate(Size<<2);
}
template<class T,int Size>
segment_tree<T,Size>::~segment_tree()
{
fd.deallocate(tr,Size<<2);
fd.deallocate(tag,Size<<2);
}
template<class T,int Size>
void segment_tree<T,Size>::build(int now,int l,int r,const T (&arr)[Size])
{
tag[now]=0;
if(l==r)
return (void)(tr[now]=arr[l]);
int mid=(l+r)>>1;
build(now<<1,l,mid,arr);
build(now<<1|1,mid+1,r,arr);
push_up(now);
}
template<class T,int Size>
lli segment_tree<T,Size>::query(int now,int gl,int gr,int l,int r)
{
lli res=0;
if(gl<=l&&gr>=r)
return tr[now];
int mid=(l+r)>>1;
push_down(now,l,r);
if(gl<=mid)
res+=query(now<<1,gl,gr,l,mid);
if(gr>mid)
res+=query(now<<1|1,gl,gr,mid+1,r);
return res;
}
template<class T,int Size>
void segment_tree<T,Size>::update(int now,int gl,int gr,int l,int r,int k)
{
if(gl<=l&&gr>=r)
return modify(now,l,r,k);
push_down(now,l,r);
int mid=(l+r)>>1;
if(gl<=mid)
update(now<<1,gl,gr,l,mid,k);
if(gr>mid)
update(now<<1|1,gl,gr,mid+1,r,k);
push_up(now);
}
template<class T,int Size>
void segment_tree<T,Size>::push_down(int now,int l,int r)
{
int mid=(l+r)>>1;
modify(now<<1,l,mid,tag[now]);
modify(now<<1|1,mid+1,r,tag[now]);
tag[now]=0;
}