线段树
(待补充
#include<bits/stdc++.h>
using namespace std;
const int N=500010;
struct node {
int l,r;
int val;
} t[4*N]; //4倍空间
int a[N];//存数
int n,p,q;
long long ans;
void build(int p,int l,int r) { //建树
t[p].l=l;
t[p].r=r;//赋值,确定左右端点
if(t[p].l==t[p].r) { //重复,即叶子节点
t[p].val=a[l];//赋值
return ;
}
int mid=(l+r)/2;//中点
if(l<=mid)build(p*2,l,mid);//建左子树
if(r>mid)build(p*2+1,mid+1,r);//建右子树
t[p].val=t[p*2].val+t[p*2+1].val;//算区间和
}
void change(int p,int x,int k) { //改数值
int l=t[p].l,r=t[p].r;//提取左右值
if(l==r) { //找到目标位置(叶子节点)
t[p].val+=k;//加上
return ;
}
int mid=(l+r)/2;
if(x<=mid)change(p*2,x,k);//如果在左边搜左子树
else change(p*2+1,x,k);//其他情况搜右子树
t[p].val=t[p*2].val+t[p*2+1].val;//更新区间和
}
void query(int p,int l,int r) { //找区间和
if(t[p].l>=l&&t[p].r<=r) { //在范围内就不用往下搜了
ans=ans+t[p].val;
return ;
}
int mid=(t[p].l+t[p].r)/2;
if(mid>=l)query(p*2,l,r);//如果左子树在区间范围内就搜下去
if(r>mid)query(p*2+1,l,r);//右边同理
}
int main() {
scanf("%d%d%d",&n,&p,&q);
for(int i=1; i<=n; i++)scanf("%d",&a[i]);
build(1,1,n);//从根节点开始建树,区间范围是1-n
for(int i=1; i<=p; i++) {
int xd,dx;
cin>>xd>>dx;//加上一个数
change(1,xd,dx);
}
for(int i=1; i<=q; i++) {
int xd,dx;
cin>>xd>>dx;
ans=0;
query(1,xd,dx);
cout<<ans<<endl;//求区间和
}
return 0;
}

浙公网安备 33010602011771号