zoukankan      html  css  js  c++  java
  • Luogu P3372【模板】线段树 1

    题目描述

    如题,已知一个数列,你需要进行下面两种操作:

    1.将某区间每一个数加上x

    2.求出某区间每一个数的和

    输入输出格式

    输入格式:

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含3或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

    操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

    输出格式:

    输出包含若干行整数,即为所有操作2的结果。

    输入输出样例

    输入样例#1: 复制
    5 5
    1 5 4 2 3
    2 2 4
    1 2 3 2
    2 3 4
    1 1 5 1
    2 1 4
    输出样例#1: 复制
    11
    8
    20

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=1000,M<=10000

    对于100%的数据:N<=100000,M<=100000

    (数据已经过加强^_^,保证在int64/long long数据范围内)

    注意long long

     1 //2018年2月22日21:12:39
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 const int N = 1000000;
     8 int n, m;
     9 long long a[N];
    10 long long A[N<<2], sum[N<<1], size[N<<1];
    11 
    12 void change(int k1){
    13     sum[k1] = sum[k1*2] + sum[k1*2+1]; 
    14 }
    15 
    16 void buildtree(int k1, int l, int r){
    17     size[k1] = r-l+1;
    18     if(l == r){
    19         sum[k1] = a[l];
    20         return;
    21     }
    22     int mid = l+r >> 1;
    23     buildtree(k1*2, l, mid);
    24     buildtree(k1*2+1, mid+1, r);
    25     change(k1); 
    26 }
    27 
    28 void add(int k1, int x){
    29     A[k1] += x;
    30     sum[k1] = sum[k1] + size[k1]*x;
    31 }
    32 void pushdown(int k1){
    33     if(A[k1]){
    34         add(k1*2, A[k1]);
    35         add(k1*2+1, A[k1]);
    36         A[k1] = 0;
    37     }
    38 }
    39 
    40 void addall(int k1, int l, int r, int L, int R, int x){
    41     if(l>R || r<L) return;
    42     if(l>=L && r<=R){
    43         add(k1, x);
    44         return;
    45     }
    46     int mid = l+r >> 1;
    47     pushdown(k1);
    48     addall(k1*2, l, mid, L, R, x);
    49     addall(k1*2+1, mid+1, r, L, R, x);
    50     change(k1);
    51 }
    52 
    53 long long find(int k1, int l, int r, int L, int R){
    54     if(l>R || r<L) return 0;
    55     if(l>=L && r<=R) return sum[k1];
    56     int mid = l+r >> 1;
    57     pushdown(k1);
    58     return (find(k1*2, l, mid, L, R) + find(k1*2+1, mid+1, r, L, R));
    59 }
    60 
    61 int main(){
    62     scanf("%d%d", &n, &m);
    63     for(int i=1;i<=n;i++)
    64         scanf("%lld", &a[i]);
    65     buildtree(1, 1, n);
    66     for(int i=1;i<=m;i++){
    67         int k1, k2, k3;
    68         scanf("%d%d%d", &k1, &k2, &k3);
    69         if(k1 == 1){
    70             long long k4;
    71             scanf("%lld", &k4);
    72             addall(1, 1, n, k2, k3, k4);
    73         }else if(k1 == 2){
    74             printf("%lld
    ", find(1, 1, n, k2, k3));
    75         }
    76     }
    77 
    78     return 0;
    79 }
  • 相关阅读:
    python-scapy学习笔记-(1)
    python系统性能模块笔记
    Python爬虫总结
    pm2的的常用命令及用法
    Javascript的map与forEach的区别
    对MVVM思想的在认识
    RN的打包
    undefined与null的区别
    rem与em的区别
    JS的函数参数传递为值传递
  • 原文地址:https://www.cnblogs.com/sineagle/p/8460251.html
Copyright © 2011-2022 走看看