2018年全国多校算法寒假训练营练习比赛(第五场)B(简单线段树)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/albertluf/article/details/79373130
链接:https://www.nowcoder.com/acm/contest/77/B
来源:牛客网

题目描述

给一个数列,会有多次询问,对于每一次询问,会有两种操作:
1:给定两个整数x, y, 然后在原数组的第x位置上加y;
2:给定两个整数l,r,然后输出数组从第l位加到第r位数字的和并换行

输入描述:

第一行有两个整数n, m(1 <= n, m <= 100000)代表数列的长度和询问的次数
第二行n个数字,对于第i个数字a[i],(0<=a[i]<=100000)。
接下来m行,每一行有三个整数f, x, y。第一个整数f是1或者是2,代表操作类型,如果是1,接下来两个数x,y代表第x的位置上加y,如果是2,则求x到y的和,保证数据合法。

输出描述:

输出每次求和的结果并换行


:简单的单点修改+区间求和

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int maxn=1e5+7;
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
ll a[maxn],sum[maxn<<2];
void build(int l,int r,int rt)
{
    if(l==r)
    {
        sum[rt]=a[l];
        return;
    }
    int m=(l+r)>>1;
    build(l,m,lson);
    build(m+1,r,rson);
    sum[rt]=sum[lson]+sum[rson];
}
void update(int L,int l,int r,int rt)
{
    if(l==r)
    {
        sum[rt]=a[l];
        return;
    }
    int m=(l+r)>>1;
    if(L<=m)update(L,l,m,lson);
    else update(L,m+1,r,rson);
    sum[rt]=sum[lson]+sum[rson];
}
ll query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&R>=r)
        return sum[rt];
    int m=(l+r)>>1;
    ll ans=0;
    if(L<=m)ans+=query(L,R,l,m,lson);
    if(R>m)ans+=query(L,R,m+1,r,rson);
    return ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    int i,j;
    for(i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    build(1,n,1);
    while(m--)
    {
        int x,y;scanf("%d%d",&x,&y);
        if(x==1)
        {
            ll z;scanf("%lld",&z);
            a[y]+=z;
            update(y,1,n,1);
        }
        else
        {
            int z;
            scanf("%d",&z);
            printf("%lld\n",query(y,z,1,n,1));
        }
    }
    return 0;
}


展开阅读全文

没有更多推荐了,返回首页