• ACM学习历程——POJ3468 A Simple Problem with Integers(线段树)


    Description

    You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

    Input

    The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000. The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000. Each of the next Q lines represents an operation. "C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000. "Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

    Output

    You need to answer all Q commands in order. One answer in a line.

    Sample Input

    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4 4
    Q 1 10
    Q 2 4
    C 3 6 3
    Q 2 4
    

    Sample Output

    4
    55
    9
    15

    Hint

    The sums may exceed the range of 32-bit integers.
     
    这是对区间所有点增固定值类的线段树。
     
    代码:
    #include <iostream>
    #include <cstdio>
    #define LL long long
    
    using namespace std;
    
    int n, q;
    
    //线段树
    const int maxn = 100000;
    struct node
    {
        int lt, rt;
        LL val, add;
    }tree[4*maxn];
    
    //建立线段树
    void Build(int lt, int rt, int id)
    {
        tree[id].lt = lt;
        tree[id].rt = rt;
        tree[id].val = 0;//每段的初值,根据题目要求
        tree[id].add = 0;
        if (lt == rt)
        {
            scanf("%I64d", &tree[id].val);
            //tree[id].add = ??;
            return;
        }
        int mid = (lt + rt) >> 1;
        Build(lt, mid, id << 1);
        Build(mid + 1, rt, id << 1 | 1);
        tree[id].val = tree[id<<1].val + tree[id<<1|1].val;
    }
    
    void PushDown(int id, int pls)
    {
        tree[id<<1].add += tree[id].add;
        //tree[id<<1].val += (pls-(pls>>1))*tree[id].add;
        tree[id<<1].val += (tree[id<<1].rt-tree[id<<1].lt+1)*tree[id].add;
        tree[id<<1|1].add += tree[id].add;
        //tree[id<<1|1].val += (pls>>1)*tree[id].add;
        tree[id<<1|1].val += (tree[id<<1|1].rt-tree[id<<1|1].lt+1)*tree[id].add;
        tree[id].add = 0;
    }
    
    //增加区间内每个点固定的值
    void Add(int lt, int rt, int id, int pls)
    {
        if (lt <= tree[id].lt && rt >= tree[id].rt)
        {
            tree[id].add += pls;
            tree[id].val += pls * (tree[id].rt-tree[id].lt+1);
            return;
        }
        if (tree[id].add != 0)
        {
            PushDown(id, tree[id].rt-tree[id].lt+1);
        }
        int mid = (tree[id].lt + tree[id].rt) >> 1;
        if (lt <= mid)
            Add(lt, rt, id<<1, pls);
        if (rt > mid)
            Add(lt, rt, id<<1|1, pls);
       tree[id].val = tree[id<<1].val + tree[id<<1|1].val;
    }
    
    LL Query(int lt, int rt, int id)
    {
        if (lt <= tree[id].lt && rt >= tree[id].rt)
            return tree[id].val;
        if (tree[id].add != 0)
        {
            PushDown(id, tree[id].rt-tree[id].lt+1);
        }
        int mid = (tree[id].lt + tree[id].rt) >> 1;
        LL ans = 0;
        if (lt <= mid)
            ans += Query(lt, rt, id<<1);
        if (rt > mid)
            ans += Query(lt, rt, id<<1|1);
        return ans;
    
    }
    
    int main()
    {
        //freopen("in.txt", "r", stdin);
        char op;
        int a, b, k;
        while (scanf("%d%d", &n, &q) != EOF)
        {
            Build(1, n, 1);
            for (int i = 0; i < q; ++i)
            {
                getchar();
                op = getchar();
                getchar();
                scanf("%d%d", &a, &b);
                if (op == 'Q')
                    printf("%I64d
    ", Query(a, b, 1));
                else
                {
                    scanf("%d", &k);
                    Add(a, b, 1, k);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    myBatis07 案例实践
    mySql开启远程连接
    myBatis05 ResultMap
    centos7.8使用yum安装mysql5.7.30图文结合,手把手教会你
    flowable: parent 'xxxxxx' was updated by another transaction concurrently
    如何在后台运行Linux命令或者脚本
    Linux查看系统是32位还是64位
    Linux中的硬链接和软链接
    Linux中计算文本行数与字数必备命令WC的用法
    Linux中8个有用的touch命令
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4430335.html
Copyright © 2020-2023  润新知