• [线段树]模板1


    【模板】线段树1

    题目描述

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

    1.令数列中的某个数加上某个数

    2.求一个区间的和

    3.查询一段区间内的最大值;

    4.查询一段区间内的最小值;

    输入

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

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

    接下来共有q行,每行有三个数

    第1个数为操作类型,具体如下

    若是第1种操作,接下来两个数x,y分别表示将第x个数加y

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

    输出

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

    样例输入

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

    样例输出

    10
    5
    1

    提示

    1<=n,q<=200000


    保证所有数据在c/c++语言的INT范围内,pascal语言的longint范围内。

    代码:

     1 #include <cstdio>
     2 #define MAXN 200005
     3 #define TREE_SIZE 530000
     4 
     5 struct node {
     6     int sum, min, max;
     7 } t[TREE_SIZE];
     8 
     9 int n, m, a[MAXN];
    10 inline int min(int a, int b) {
    11     return a < b ? a : b; 
    12 }
    13 inline int max(int a, int b) {
    14     return a > b ? a : b;
    15 }
    16 inline node join(node a, node b) {
    17     node c;
    18     c.sum = a.sum +b.sum;
    19     c.max = max(a.max, b.max);
    20     c.min = min(a.min, b.min);
    21     return c;
    22 }
    23 void build(int l, int r, int k) {
    24     if (l == r) {
    25         t[k].sum =t [k].min = t[k].max = a[l];
    26         return;
    27     }
    28     int mid = l + r >> 1;
    29     build(l, mid, k << 1);
    30     build(mid + 1, r, k << 1 | 1);
    31     t[k] = join(t[k << 1], t[k << 1 | 1]);
    32 }
    33 node query(int l, int r, int a, int b, int k) {
    34     if(l >= a && r <= b) {
    35         return t[k];
    36     }
    37     int mid = l + r >> 1;
    38     if (b <= mid) {
    39         return query(l, mid, a, b, k << 1);
    40     }
    41     if (a > mid) {
    42         return query(mid + 1, r, a, b, k << 1 | 1);
    43     }
    44     return join(query(l, mid, a, b, k << 1), query(mid + 1, r, a, b, k << 1 | 1));
    45 }
    46 void modify_s(int l, int r, int a, int b, int k) {
    47     if (l == a && r == a) {
    48         t[k].sum += b;
    49         t[k].max = t[k].min = t[k].sum;
    50         return;
    51     }
    52     int mid = l + r >> 1;
    53     if (a <= mid) {
    54         modify_s(l, mid, a, b, k << 1);
    55     }
    56     else {
    57         modify_s(mid + 1, r, a, b, k << 1 | 1);
    58     }
    59     t[k] = join(t[k << 1], t[k << 1 | 1]);
    60 }
    61 int main() {
    62     int o, b, c;
    63     scanf("%d%d", &n, &m);
    64     for(int i = 1; i <= n; ++i) {
    65         scanf("%d",a + i);
    66     }
    67     build(1, n, 1);
    68     while (m--) {
    69         scanf("%d %d %d", &o, &b, &c);
    70         if (o == 1) {
    71             modify_s(1, n, b, c, 1); 
    72         }
    73         if (o == 2) {
    74             printf("%d
    ", query(1, n, b, c, 1).sum); 
    75         }
    76         if (o == 3) {
    77             printf("%d
    ", query(1, n, b, c, 1).max); 
    78         }
    79         if (o == 4) {
    80             printf("%d
    ",query(1, n, b, c, 1).min);
    81         }
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    azure 控制台小工具
    azure flask 测试
    azure django bug
    Ubuntu 18.04中使用Mac OS风格的Dock启动器替换左侧面板
    刚安装的程序要卸载,如何Ubuntu查看程序安装记录
    Ubuntu添加字体
    Ubuntu下的图形化多线程下载器XDM
    Linux命令行基础操作
    linux使用管理员权限打开一个文件管理器(右键root打开文件)
    ubuntu美化1——主题、图标、dock(dock相当于windows的开始菜单和任务栏)
  • 原文地址:https://www.cnblogs.com/GldHkkowo/p/8849496.html
Copyright © 2020-2023  润新知