zoukankan      html  css  js  c++  java
  • 线段树模板

    博客:

    模板:

    成段更新:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define LL long long
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    const int maxn = 111111;
    LL addv[maxn<<2];
    LL sumv[maxn<<2];
    //int maxv[maxn<<2];
    void PushUp(int rt) {
    //    maxv[rt] = max(maxv[rt<<1], maxv[rt<<1|1]);
        sumv[rt] = sumv[rt<<1] + sumv[rt<<1|1];
    }
    void PushDown(int rt,int m) {
        if (addv[rt]) {
            addv[rt<<1] += addv[rt];
            addv[rt<<1|1] += addv[rt];
            sumv[rt<<1] += addv[rt] * (m - (m >> 1));
            sumv[rt<<1|1] += addv[rt] * (m >> 1);
            // maxv[rt<<1] += addv[rt];
            // maxv[rt<<1|1] += addv[rt];
            addv[rt] = 0;
        }
    }
    void build(int l,int r,int rt) {
        addv[rt] = 0;
        if (l == r) {
            scanf("%I64d",&sumv[rt]);
            //scanf("%d", &maxv[rt]);
            return ;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        PushUp(rt);
    }
    void update(int L,int R,int c,int l,int r,int rt) {
        if (L <= l && r <= R) {
            addv[rt] += c;
            sumv[rt] += (LL)c * (r - l + 1);
            //maxv[rt] += c
            return ;
        }
        PushDown(rt , r - l + 1);
        int m = (l + r) >> 1;
        if (L <= m) update(L , R , c , lson);
        if (m < R) update(L , R , c , rson);
        PushUp(rt);
    }
    LL query(int L,int R,int l,int r,int rt) {
        if (L <= l && r <= R) {
            //return maxv[rt];
            return sumv[rt];
        }
        PushDown(rt , r - l + 1);
        int m = (l + r) >> 1;
        LL ret = 0;
        if (L <= m) ret += query(L, R, lson);
                    //ret = max(ret, query(L , R , lson));
                    
        if (m < R)  ret += query(L, R, rson);
                    //ret = max(ret, query(L , R , rson));
                    
        return ret;
    }
    int main() {
        int N , Q;
        scanf("%d%d",&N,&Q);
        build(1 , N , 1);
        while (Q --) {
            char op[2];
            int a , b , c;
            scanf("%s",op);
            if (op[0] == 'Q') {
                scanf("%d%d",&a,&b);
                printf("%I64d
    ",query(a , b , 1 , N , 1));
            } else {
                scanf("%d%d%d",&a,&b,&c);
                update(a , b , c , 1 , N , 1);
            }
        }
        return 0;
    }
    View Code

    成段置值:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    const int maxn = 111111;
    int h , w , n;
    int col[maxn<<2];
    int sum[maxn<<2];
    void PushUp(int rt) {
           sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    }
    void PushDown(int rt,int m) {
           if (col[rt]) {
                  col[rt<<1] = col[rt<<1|1] = col[rt];
                  sum[rt<<1] = (m - (m >> 1)) * col[rt];
                  sum[rt<<1|1] = (m >> 1) * col[rt];
                  col[rt] = 0;
           }
    }
    void build(int l,int r,int rt) {
           col[rt] = 0;
           sum[rt] = 1;
           if (l == r) return ;
           int m = (l + r) >> 1;
           build(lson);
           build(rson);
           PushUp(rt);
    }
    int query(int L,int R,int l,int r,int rt) {//求和写法,参数信息=>(问询区间左端点,问询区间右端点,总区间左端点,总区间右端点,根节点编号)
        if (L <= l && r <= R) {
            return sumv[rt];
        }
        int m = l + ((r - l)>>1);
        int ret = 0;
        if (L <= m) ret += query(L , R , lson);
        if (R > m) ret += query(L , R , rson);
        return ret;
    }
    void update(int L,int R,int c,int l,int r,int rt) {
           if (L <= l && r <= R) {
                  col[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 , lson);
           if (R > m) update(L , R , c , rson);
           PushUp(rt);
    }
    
    int main() {
           int T , n , m;
           scanf("%d",&T);
           for (int cas = 1 ; cas <= T ; cas ++) {
                  scanf("%d%d",&n,&m);
                  build(1 , n , 1);
                  while (m --) {
                         int a , b , c;
                         scanf("%d%d%d",&a,&b,&c);
                         update(a , b , c , 1 , n , 1);
                  }
                  printf("Case %d: The total value of the hook is %d.
    ",cas , sum[1]);
           }
           return 0;
    }
    View Code

    单点更新:

    /*
    说明:
    此模板支持对于线段的单点加减操作更新、区间最值or和的查询
    下面主要以求和操作为例,注释部分为求最值功能,根据自己的
    需求适当修改模板
    
    验证题目:HDU 1166 敌兵布阵 (以下代码也是解决此题的代码)
    */
    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    const int maxn = 50005;//maxn = 线段的最大长度 则=> maxn<<2 = 线段树可能的最多结点
    //int maxv[maxn<<2];//保存最大值
    //int minv[maxn<<2];//保存最小值
    int sumv[maxn<<2];//保存区间和
    void PushUP(int rt) {
        //maxv[rt] = max(maxv[rt<<1] , maxv[rt<<1|1]);
        //minv[rt] = min(minv[rt<<1], minv[rt<<1|1]);
        sumv[rt] = sumv[rt<<1] + sumv[rt<<1|1];
    }
    void build(int l,int r,int rt) {//设置初始值
        if (l == r) {
            // scanf("%d",&maxv[rt]);
            // scanf("%d", &minv[rt]);
            scanf("%d", &sumv[rt]);
            return ;
        }
        int m = l + ((r - l)>>1);
        build(lson);
        build(rson);
        PushUP(rt);
    }
    void update(int p,int sc,int l,int r,int rt) {//单点更新,参数(更新点,更新值,总区间左端点,总区间右端点,根节点编号)
        if (l == r) {
            //maxv[rt] = sc;
            //minv[rt] = sc;
            sumv[rt] += sc;
            return ;
        }
        int m = l + ((r - l)>>1);
        if (p <= m) update(p , sc , lson);
        else update(p , sc , rson);
        PushUP(rt);
    }
    // int query(int L,int R,int l,int r,int rt) {//查询最大值的写法、最小值同理、求和区间写法在下面
    //     if (L <= l && r <= R) {
    //         return maxv[rt];
    //     }
    //     int m = (l + r) >> 1;
    //     int ret = 0;
    //     if (L <= m) ret = max(ret , query(L , R , lson));
    //     if (R > m) ret = max(ret , query(L , R , rson));
    //     return ret;
    // }
    int query(int L,int R,int l,int r,int rt) {//求和写法,参数信息=>(问询区间左端点,问询区间右端点,总区间左端点,总区间右端点,根节点编号)
        if (L <= l && r <= R) {
            return sumv[rt];
        }
        int m = l + ((r - l)>>1);
        int ret = 0;
        if (L <= m) ret += query(L , R , lson);
        if (R > m) ret += query(L , R , rson);
        return ret;
    }
    int main(void)
    {
        int nCase;
        scanf("%d", &nCase);
        for(int t = 1; t <= nCase; t++){
            memset(sumv, 0, sizeof(sumv));
            int len;
            scanf("%d", &len);
            build(1, len, 1);
            char s[20];
            printf("Case %d:
    ", t);
            while(~scanf("%s", s) && s[0] != 'E'){//s != 'End'
                if(s[0] == 'Q'){//s = Query
                    int L, R;
                    scanf("%d %d", &L, &R);
                    printf("%d
    ", query(L, R, 1, len, 1));
                }
                else if(s[0] == 'S'){//减操作
                    int point, val;
                    scanf("%d%d", &point, &val);
                    update(point, -val, 1, len, 1);
                }
                else if(s[0] == 'A'){//加操作
                    int point, val;
                    scanf("%d%d", &point, &val);
                    update(point, val, 1, len, 1);
                }
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Java面试之最常见的十道面试题(超经典)
    hdu 3939(勾股+容斥)
    poj 1845 (逆元 + 约数和)
    hdu 5607 BestCoder Round #68 (矩阵快速幂)
    中国剩余定理
    Math
    (⊙o⊙)…
    lucas定理
    hdu 5600 BestCoder Round #67 (div.2)
    hdu5601 BestCoder Round #67 (div.2)
  • 原文地址:https://www.cnblogs.com/linhaitai/p/9949501.html
Copyright © 2011-2022 走看看