• poj 3468 A Simple Problem with Integers 【线段树-成段更新】


    题目:poj 3468 A Simple Problem with Integers


    题意:给出n个数。两种操作

    1:l -- r 上的全部值加一个值val

    2:求l---r 区间上的和


    分析:线段树成段更新,成段求和

    树中的每一个点设两个变量sum 和 num ,分别保存区间 l--r 的和 和l---r 每一个值要加的值

    对于更新操作:对于要更新到的区间上面的区间,直接进行操作 加上 (r - l +1)* val 。

    以下的区间标记num += val

    对于求和操作。每次进行延迟更新。把num值分别更新到两个子区间。sum值更新,然后num值变为0


    注意:这个题目会超int 。

    所以


    AC代码:

    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <math.h>
    #include <vector>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    const long long N = 110000;
    const long long inf = 0x3f3f3f3f;
    struct Node
    {
        long long l,r;
        long long num,sum;
    };
    Node tree[5*N];
    long long a[N];
    long long cnt ;
    void build(long long o,long long l,long long r)
    {
        tree[o].l = l,tree[o].r = r;
        tree[o].num = 0;
        if(l==r)
        {
            tree[o].sum = a[cnt++];
            return ;
        }
        long long mid = (l+r)/2;
        build(o+o,l,mid);
        build(o+o+1,mid+1,r);
        tree[o].sum = tree[o+o].sum + tree[o+o+1].sum;
    }
    void push_update(long long o)
    {
        if(tree[o].num!=0)
        {
            tree[o].sum += tree[o].num * (tree[o].r-tree[o].l+1);
            tree[o+o+1].num += tree[o].num;
            tree[o+o].num += tree[o].num;
            tree[o].num = 0;
        }
    }
    void update(long long o,long long l,long long r,long long val)
    {
        if(l==tree[o].l && r == tree[o].r)
        {
            tree[o].num += val;
            return ;
        }
        tree[o].sum += (val*(r-l+1)); //维护前面的
        long long mid = (tree[o].l+tree[o].r) / 2;
        if(r<=mid)
            update(o+o,l,r,val);
        else if(l>mid)
            update(o+o+1,l,r,val);
        else
        {
            update(o+o,l,mid,val);
            update(o+o+1,mid+1,r,val);
        }
    }
    long long query(long long o,long long l,long long r)
    {
        if(tree[o].l==l && tree[o].r == r)
        {
            return tree[o].sum+(r-l+1)*tree[o].num;
        }
        push_update(o); //维护后面的
        long long mid = (tree[o].l+tree[o].r)/2;
        if(r<=mid)
            return query(o+o,l,r);
        else if(l>mid)
            return query(o+o+1,l,r);
        else
            return query(o+o,l,mid) + query(o+o+1,mid+1,r);
    }
    int main()
    {
        //freopen("Input.txt","r",stdin);
        long long n,m;
        while(~scanf("%lld%lld",&n,&m))
        {
            cnt = 0;
            for(long long i=0;i<n;i++)
                scanf("%lld",&a[i]);
            build(1,1,n);
            while(m--)
            {
                getchar();
                char c;
                long long x,y;
                scanf("%c",&c);
                scanf("%lld%lld",&x,&y);
                //printf("*****************************************
    ");
                if(c=='Q')
                {
                    printf("%lld
    ",query(1,x,y));
                }
                else
                {
                    long long val;
                    scanf("%lld",&val);
                    update(1,x,y,val);
                }
            }
        }
        return 0;
    }
    


  • 相关阅读:
    若没有特殊说明,博文密码都是我的生日
    「考前日志」11.18
    「考前日志」11.17
    洛谷 P2018 消息传递
    「考前日志」11.16
    「考前日志」11.15
    「考前日志」11.14
    2020.11.13 “考试”
    「考前日志」11.13
    AcWing277 饼干
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7233345.html
Copyright © 2020-2023  润新知