P3372 模板线段树 1

Posted arknight

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3372 模板线段树 1相关的知识,希望对你有一定的参考价值。

题目

P3372 【模板】线段树 1

提交   121.16k
通过    48.14k
时间限制    1.00s
内存限制    125.00MB
题目提供者   HansBug
难度   普及/提高-
历史分数   100
 提交记录       查看题解

标签

题目描述

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

  1. 将某区间每一个数加上 kk。
  2. 求出某区间每一个数的和。

输入格式

第一行包含两个整数 n, mn,m,分别表示该数列数字的个数和操作的总个数。

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

接下来 mm 行每行包含 33 或 44 个整数,表示一个操作,具体如下:

  1.  1 x y k:将区间 [x, y][x,y] 内每个数加上 kk。
  2.  2 x y:输出区间 [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

说明/提示

对于 30% 的数据:n8,m10。
对于 70% 的数据:n103m104
对于 100% 的数据:1n,m105

保证任意时刻数列中任意元素的和在 [-263, 263)内。

【样例解释】

技术图片

代码

不多说了,线段树板子题。

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1000090;

long long nums[MAXN];
long long totN;
long long totDO;
bool tempquest;

struct Node
{
    long long tag;
    long long value;
    long long l, r;
    Node* lch, * rch;
    inline void maketag(const long long w)
    {
        value += (r - l + 1) * w;
        tag += w;
    }
    inline void push_up()
    {
        value = lch->value + rch->value;
    }
    inline void push_down()
    {
        if (!tag)
        {
            return;
        }
        else
        {
            if (lch==NULL)
            {
                Node(l, (l + r) >> 1);
            }
            if (rch == NULL)
            {
                Node(((l + r) >> 1) + 1, r);
            }
            lch->maketag(tag);
            rch->maketag(tag);
            tag = 0;
        }
    }
    Node(const long long L, const long long R)
    {
        l = L;
        r = R;
        if (l == r)
        {
            value = nums[l];
            lch = NULL;
            rch = NULL;
            tag = 0;
        }
        else
        {
            tag = 0;
            long long mid = (l + r) >> 1;
            lch = new Node(L, mid);
            rch = new Node(mid + 1, R);
            push_up();
        }
    }
    inline bool in_range(const long long L, const long long R)
    {
        return (L <= l) && (R >= r);
    }
    inline bool out_of_range(const long long L, const long long R)
    {
        return (l > R) || (r < L);
    }
    inline void update(const long long L, const long long R, const long long w)
    {
        if (in_range(L, R))
        {
            maketag(w);
        }
        else if (!out_of_range(L, R))
        {
            push_down();
            lch->update(L, R, w);
            rch->update(L, R, w);
            push_up();
        }
    }
    inline long long quest_range_sum(const long long L, const long long R)
    {
        if (in_range(L, R))
        {
            return value;
        }
        else
        {
            if (out_of_range(L, R))
            {
                return 0;
            }
        }
        push_down();
        return lch->quest_range_sum(L, R) + rch->quest_range_sum(L, R);
    }
};

inline long long read()
{
    long long x = 0;
    short f = 1;
    char ch = getchar();
    while (ch < 0 || ch>9)
    {
        if (ch == -)
            f = -1;
        ch = getchar();
    }
    while (ch >= 0 && ch <= 9)
    {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
void write(const long long& x)
{
    char f[100];
    long long tmp = x;
    if (tmp < 0)
    {
        tmp = -tmp;
        putchar(-);
    }
    long long s = 0;
    while (tmp > 0)
    {
        f[s++] = tmp % 10 + 0;
        tmp /= 10;
    }
    while (s > 0)
    {
        putchar(f[--s]);
    }
}

int main()
{
    totN = read();
    totDO = read();
    int temp;
    for (int i = 1; i <= totN; i++)
    {
        nums[i] = read();
    }
    Node* root = new Node(1, totN);
    for (int i = 1; i <= totDO; i++)
    {
        tempquest = read() - 1;
        if (!tempquest)
        {
            long long tempL = read();
            long long tempR = read();
            auto tempW = read();
            root->update(tempL, tempR, tempW);
        }
        else
        {
            auto tempL = read();
            auto tempR = read();
            write(root->quest_range_sum(tempL, tempR));
            putchar(
);
        }
    }
    return 0;
}//LikiBlaze Code

 

以上是关于P3372 模板线段树 1的主要内容,如果未能解决你的问题,请参考以下文章

P3372 模板线段树 1

P3372 模板线段树 1(区间修改区间查询)(树状数组)

P3372 模板线段树 1

线段树模板1 [Luogu P3372]

洛谷P3372 模板线段树 1

P3372 模板线段树 1