线段树入门——区间求和,区间更新(模板)

安稳与你 提交于 2020-01-05 03:16:08

线段树入门 区间求和,区间更新。

题目链接:https://cn.vjudge.net/problem/POJ-3468

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=100000;
const int maxsize=4*maxn;

struct Node
{
    ll sum;
    ll tag;
};

Node data[maxsize];

void add(int v,int a,int b,int k,int l,int r)
{
    if(b<=l||a>=r)
        return;
    if(a<=l&&b>=r)
        data[k].tag+=v;
    else
    {
        data[k].sum+=(min(r,b)-max(l,a))*v;
        add(v,a,b,2*k+1,l,(l+r)/2);
        add(v,a,b,2*k+2,(l+r)/2,r);
    }
}

ll query(int a,int b,int k,int l,int r)
{
    if(b<=l||a>=r)
        return 0;
    if(a<=l&&b>=r)
        return data[k].tag*(r-l)+data[k].sum;

    ll sum=0;
    sum+=data[k].tag*(min(r,b)-max(l,a));
    sum+=query(a,b,2*k+1,l,(l+r)/2);
    sum+=query(a,b,2*k+2,(l+r)/2,r);

    return sum;
}

int main()
{
    int n,q,t,a,b;
    char c;
    scanf("%d%d",&n,&q);

    for(int i=0;i<n;++i)
    {
        scanf("%d",&t);
        add(t,i,i+1,0,0,n);
    }

    while(q--)
    {
        scanf("%*c%c%d%d",&c,&a,&b);
        if(c=='Q')
            printf("%lld\n",query(a-1,b,0,0,n));
        else
        {
            scanf("%d",&t);
            add(t,a-1,b,0,0,n);
        }
    }

    return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!