线段树模板

 

/** 有 n 个数和 5 种操作
add a b c:把区间[a,b]内的所有数都增加 c
set a b c:把区间[a,b]内的所有数都设为 c
sum a b:查询区间[a,b]的区间和
max a b:查询区间[a,b]的最大值
min a b:查询区间[a,b]的最小值
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 7;
const long long INF = 1LL << 62;
struct Segment_tree {
    struct Node {
        int l, r;
        long long sum, max, min, set_lazy, add_lazy;
    } tre[maxn << 2];
    long long arr[maxn];
    inline void push_up(int rt) {
        if(tre[rt].l == tre[rt].r) {
            return ;
        }
        tre[rt].sum = tre[rt<<1].sum + tre[rt<<1|1].sum;
        tre[rt].max = max(tre[rt<<1].max, tre[rt<<1|1].max);
        tre[rt].min = min(tre[rt<<1].min, tre[rt<<1|1].min);
    }
    inline void push_down(int rt) {
        if(tre[rt].set_lazy) { ///if set_lazy add_lazy = 0
            tre[rt<<1].set_lazy = tre[rt].set_lazy;
            tre[rt<<1].sum = (tre[rt<<1].r - tre[rt<<1].l + 1) * tre[rt].set_lazy;
            tre[rt<<1].max = tre[rt].set_lazy;
            tre[rt<<1].min = tre[rt].set_lazy;
            tre[rt<<1|1].set_lazy = tre[rt].set_lazy;
            tre[rt<<1|1].sum = (tre[rt<<1|1].r - tre[rt<<1|1].l + 1) * tre[rt].set_lazy;
            tre[rt<<1|1].max = tre[rt].set_lazy;
            tre[rt<<1|1].min = tre[rt].set_lazy;
            tre[rt].add_lazy = 0;
            tre[rt<<1].add_lazy = tre[rt<<1|1].add_lazy = 0;
            tre[rt].set_lazy = 0;
            return ;
        }
        if(tre[rt].add_lazy) {
            tre[rt<<1].add_lazy += tre[rt].add_lazy;
            tre[rt<<1].sum += (tre[rt<<1].r - tre[rt<<1].l + 1) * tre[rt].add_lazy;
            tre[rt<<1].max += tre[rt].add_lazy;
            tre[rt<<1].min += tre[rt].add_lazy;
            tre[rt<<1|1].add_lazy += tre[rt].add_lazy;
            tre[rt<<1|1].sum += (tre[rt<<1|1].r - tre[rt<<1|1].l + 1) *
                                tre[rt].add_lazy;
            tre[rt<<1|1].max += tre[rt].add_lazy;
            tre[rt<<1|1].min += tre[rt].add_lazy;
            tre[rt].add_lazy = 0;
        }
    }
    void build(int rt,int l,int r) {
        tre[rt].l = l;
        tre[rt].r = r;
        tre[rt].set_lazy = 0;
        tre[rt].add_lazy = 0;
        if(l == r) {
            tre[rt].sum = tre[rt].max = tre[rt].min = arr[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        push_up(rt);
    }
    void update1(int rt,int l,int r,long long val) { ///add
        push_down(rt);
        if(l == tre[rt].l && tre[rt].r == r) {
            tre[rt].add_lazy = val;
            tre[rt].sum += (tre[rt].r - tre[rt].l + 1) * val;
            tre[rt].max += val;
            tre[rt].min += val;
            return ;
        }
        int mid = (tre[rt].l + tre[rt].r) >> 1;
        if(r <= mid) {
            update1(rt<<1,l,r,val);
        } else if(l > mid) {
            update1(rt<<1|1,l,r,val);
        } else {
            update1(rt<<1,l,mid,val);
            update1(rt<<1|1,mid+1,r,val);
        }
        push_up(rt);
    }
    void update2(int rt,int l,int r,long long val) { ///set
        push_down(rt);
        if(l == tre[rt].l && tre[rt].r == r) {
            tre[rt].set_lazy = val;
            tre[rt].sum = (tre[rt].r - tre[rt].l + 1) * val;
            tre[rt].max = val;
            tre[rt].min = val;
            tre[rt].add_lazy = 0;
            return ;
        }
        int mid = (tre[rt].l + tre[rt].r) >> 1;
        if(r <= mid) {
            update2(rt<<1,l,r,val);
        } else if(l > mid) {
            update2(rt<<1|1,l,r,val);
        } else {
            update2(rt<<1,l,mid,val);
            update2(rt<<1|1,mid+1,r,val);
        }
        push_up(rt);
    }
    long long query1(int rt,int l,int r) { ///sum
        push_down(rt);
        if(l == tre[rt].l && tre[rt].r == r) {
            return tre[rt].sum;
        }
        int mid = (tre[rt].l + tre[rt].r) >> 1;
        if(r <= mid) {
            return query1(rt<<1,l,r);
        } else if(l > mid) {
            return query1(rt<<1|1,l,r);
        } else {
            return query1(rt<<1,l,mid) + query1(rt<<1|1,mid+1,r);
        }
    }
    long long query2(int rt,int l,int r) { ///max
        push_down(rt);
        if(l == tre[rt].l && tre[rt].r == r) {
            return tre[rt].max;
        }
        int mid = (tre[rt].l + tre[rt].r) >> 1;
        if(r <= mid) {
            return query2(rt<<1,l,r);
        } else if(l > mid) {
            return query2(rt<<1|1,l,r);
        } else {
            return max(query2(rt<<1,l,mid), query2(rt<<1|1,mid+1,r));
        }
    }
    long long query3(int rt,int l,int r) { ///min
        push_down(rt);
        if(l == tre[rt].l && tre[rt].r == r) {
            return tre[rt].min;
        }
        int mid = (tre[rt].l + tre[rt].r) >> 1;
        if(r <= mid) {
            return query3(rt<<1,l,r);
        } else if(l > mid) {
            return query3(rt<<1|1,l,r);
        } else {
            return min(query3(rt<<1,l,mid), query3(rt<<1|1,mid+1,r));
        }
    }
} S;

 

posted @ 2018-07-23 10:46  lived  阅读(122)  评论(0编辑  收藏  举报