【问题描述】
假设有一列数 {Ai }(1 ≤ i ≤ n) ,支持如下两种操作:
(1)将 A k 的值加 D 。( k, D 是输入的数)
(2) 输出 A s +A s+1 +…+A t 。( s, t 都是输入的数, S ≤ T )
根据操作要求进行正确操作并输出结果。
【输入格式】
输入文件第一行一个整数 n(0<=n<=100000) , 第二行为 n 个整数,表示 {A i } 的初始值。
第三行为一个整数 m(0<=m<=150000) ,表示操作数 v 下接 m 行,每行描述一个操作,有如下两种情况:
ADD k d ( 表示将 A k 加 d , 1<=k<=n , d 为整数 )
SUM s t (表示输出 A s +…+A t )
【输出格式】
对于每一个 SUM 提问,输出结果
【输入输出样例】
输入:
4
1 4 2 3
3
SUM 1 3
ADD 2 50
SUM 2 3
输出:
7
56
分析:不用多说什么,就是线段树或者树状数组,我选定的是线段树,思路和我发表的上一篇【I HATE IT】是一样的。
【参考程序】:
#include<iostream>
#include<stdio.h>
using namespace std;
const int maxn=100010;
struct node
{
int a,b,sum;
int lc,rc;
} tree[maxn*2];
int a[maxn];
int tail,n,m,Sum;
void modify(int now,int left,int right,int st)
{
int a1=tree[now].a,b1=tree[now].b;
if (left==a1 && b1==right)
{
tree[now].sum=tree[now].sum+st;
return ;
}
int lcl=tree[now].lc,rcl=tree[now].rc;
int mid=(a1+b1)>>1;
if (right<=mid)
{
modify(lcl,left,right,st);
tree[now].sum=tree[tree[now].lc].sum+tree[tree[now].rc].sum;
}
else if (left>=mid)
{
modify(rcl,left,right,st);
tree[now].sum=tree[tree[now].lc].sum+tree[tree[now].rc].sum;
}
else
{
modify(lcl,left,mid,st);
modify(rcl,mid,right,st);
tree[now].sum=tree[tree[now].lc].sum+tree[tree[now].rc].sum;
}
}
void getsum(int now,int left,int right)
{
int a1=tree[now].a,b1=tree[now].b;
if (left==a1 && b1==right)
{
Sum+=tree[now].sum;
return ;
}
int lcl=tree[now].lc,rcl=tree[now].rc;
int mid=(a1+b1)>>1;
if (right<=mid) getsum(lcl,left,right);
else if (left>=mid) getsum(rcl,left,right);
else
{
getsum(lcl,left,mid);
getsum(rcl,mid,right);
}
}
void make_tree(int a1,int b1)
{
tail++;int now=tail;
tree[now].a=a1;tree[now].b=b1;
tree[now].sum=0;
tree[now].lc=tree[now].rc=-1;
if (a1+1<b1)
{
int mid=(a1+b1)>>1;
tree[now].lc=tail+1; make_tree(a1,mid);
tree[now].rc=tail+1; make_tree(mid,b1);
tree[now].sum=tree[tree[now].lc].sum+tree[tree[now].rc].sum;
}
else if (a1+1==b1) tree[now].sum=a[b1];
}
int main()
{
freopen("shulie.in","r",stdin);
freopen("shulie.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
tail=0;
make_tree(0,n);
scanf("%d",&m);
char ss[10]={0};int s,t;
for (int i=1;i<=m;i++)
{
getchar();
scanf("%s %d%d",ss,&s,&t);
if (!strcmp(ss,"SUM"))
{
Sum=0;
getsum(1,s-1,t);
printf("%d\n",Sum);
}
else modify(1,s-1,s,t);
}
return 0;
}