线段树模板

线段树模板。

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;
}
posted @ 2019-01-22 11:34  Saikbird  阅读(110)  评论(0编辑  收藏  举报