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

    【模板】线段树2

    题目描述

    给定一个无序数列,有两种操作:

    1.将一个区间内的所有点值都加上一个整数

    2.求一个区间的和

    输入

    输入的第1行,共有两个数n和q,表示数列长度和操作次数

    输入的第2行,共有n个数,表示该数列

    接下来共有q行,每行有3~4个数 第1个数为操作类型,具体如下

    若是第1种操作,接下来三个数x,y,z表示将[x,y]内所有数加上z。

    若是第2种操作,接下来两个数x,y表示闭区间的左右端点

    输出

    输出共有若干行,对于每一个询问输出一个整数结果

    样例输入

    5 5
    1 2 3 4 5
    2 1 4
    1 1 3 2
    2 2 4
    1 3 5 3
    2 1 5

    样例输出

    10
    13
    30

    提示

    1<=n,q<=200000

    保证输入的所有数据在int范围内

    代码:

     1 #include <cstdio>    
     2 #include <algorithm>    
     3 using namespace std;    
     4 #define lson l , m , rt*2    
     5 #define rson m + 1 , r , rt*2+1 
     6 #define root 1 , N , 1   
     7 const int maxn = 200001;    
     8 long long add[maxn<<2];    
     9 long long sum[maxn<<2];    
    10 
    11 void PushUp(int rt) {    
    12     sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];    
    13 }
    14    
    15 void PushDown(int rt, int m) {    
    16     if (add[rt]) {    
    17         add[rt << 1] += add[rt];    
    18         add[rt << 1 | 1] += add[rt];    
    19         sum[rt << 1] += add[rt] * (m - (m >> 1));    
    20         sum[rt << 1 | 1] += add[rt] * (m >> 1);    
    21         add[rt] = 0;    
    22     }    
    23 }    
    24 
    25 void Build(int l, int r, int rt) {    
    26     add[rt] = 0;    
    27     if (l == r) {    
    28         scanf("%lld", &sum[rt]);    
    29         return ;    
    30     }    
    31     int m = (l + r) >> 1;    
    32     Build(lson);    
    33     Build(rson);    
    34     PushUp(rt);    
    35 }    
    36 
    37 void Update(int L, int R, int c, int l, int r, int rt) {    
    38     if (L <= l && r <= R) {    
    39         add[rt] += c;    
    40         sum[rt] += (long long)c * (r - l + 1);    
    41         return ;    
    42     }    
    43     PushDown(rt, r - l + 1);    
    44     int m = (l + r) >> 1;    
    45     if (L <= m) {
    46         Update(L, R, c, lson);    
    47     }
    48     if (m < R) {
    49         Update(L, R, c, rson);    
    50     }
    51     PushUp(rt);
    52 } 
    53    
    54 long long Query(int L, int R, int l, int r, int rt) {    
    55     if (L <= l && r <= R) {    
    56         return sum[rt];    
    57     }    
    58     PushDown(rt, r - l + 1);    
    59     int m = (l + r) >> 1;    
    60     long long re = 0;    
    61     if (L <= m) {
    62         re += Query(L, R, lson);    
    63     }
    64     if (m < R) {
    65         re += Query(L, R, rson);    
    66     }
    67     return re;    
    68 }    
    69 
    70 int main() {    
    71     int N , Q;    
    72     scanf("%d%d", &N, &Q);    
    73     Build(root);    
    74     while (Q --) {    
    75         char op[2];    
    76         int a , b , c;    
    77         if (scanf("%s", op)!= 1) {
    78             break;  
    79         }
    80         if (op[0] == '2') {    
    81             scanf("%d%d", &a, &b);    
    82             printf("%lld
    ", Query(a , b ,root));    
    83         } 
    84         else {    
    85             scanf("%d%d%d", &a, &b, &c);    
    86             Update(a, b, c, root);    
    87         }    
    88     }    
    89     return 0;    
    90 }
  • 相关阅读:
    ubuntu下怎么配置/查看串口-minicom工具
    jpg与pgm(P5)的互相转换(Python)
    hyper-v安装ubuntu18的全过程+踩过的坑(win10家庭版)
    zerotier的下载、安装、配置与使用(win10、ubuntu)
    github page+jekyll构建博客的解决方案
    opencv2.4.13.7的resize函数使用(c++)
    c++中的const和volatile知识自我总结
    各种优化算法详解
    P与NP问题
    vs2017配置pthread.h的方法
  • 原文地址:https://www.cnblogs.com/GldHkkowo/p/8854225.html
Copyright © 2011-2022 走看看