链接:
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;
}