zoukankan      html  css  js  c++  java
  • 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('\n');
            }
        }
        return 0;
    }//LikiBlaze Code
  • 相关阅读:
    SharePoint学习资料收集
    VS2008 IDE界面
    罗列没有主键的表
    Google Calendar API练习
    pb中数据窗口中字段只显示255个的解决方法
    oracle 中的事务和update from 语句
    sqlserver2005数据库扩容方案
    在一个表上创建非聚集索引和聚集索引
    <xsl:applytemplates/>的应用
    时间戳转换为日期类型
  • 原文地址:https://www.cnblogs.com/genshin/p/13253338.html
Copyright © 2011-2022 走看看