题意:
中文
思路:
线段树模板题(update时可不用push_up)
代码:
#include <iostream>
#include <cstdio>
#define ls l,mid,rt<<1
#define rs mid+1,r,(rt<<1)|1
#define mi (l+r)>>1
using namespace std;
const int MAXN=200005;
long long ans,res,tree[MAXN*4],a[MAXN],T,n,st,en,ppp,m;
void push_up(int rt){
tree[rt]=tree[rt<<1]+tree[(rt<<1)|1];
return ;
}
void build(int l,int r,int rt){
if(l==r){
tree[rt]=a[++ppp];
return ;
}
int mid=mi;
build(ls);
build(rs);
push_up(rt);
return ;
}
void update(int l,int r,int rt){
tree[rt]+=en;
if(l==r) return ;
int mid=mi;
if(st<=mid)
update(ls);
else
update(rs);
return ;
}
void query(int l,int r,int rt){
if(st<=l&&r<=en){
ans+=tree[rt];
return ;
}
int mid=mi;
if(st<=mid)
query(ls);
if(en>mid)
query(rs);
return ;
}
int main(){
while(scanf("%lld",&n)!=-1){
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
ppp=0;
build(1,n,1);
char str[5];
while(1){
scanf("%s",str);
if(str[0]=='E') break;
else if(str[0]=='S'){
scanf("%lld %lld",&st,&en);
getchar();
long long temp=en;
en=en-a[st];
a[st]=temp;
update(1,n,1);
}else if(str[0]=='M'){
scanf("%lld%lld",&st,&en);
getchar();
ans=0;
query(1,n,1);
printf("%lld\n",ans);
}
}
}
}
Description
给定n个数,你的任务是实现下面的两种操作,S x y把第x个数改成y(y是小于10的9次方的非负整数),M x y计算第x个数到第y个数的和
Input
多组数据,第一行为整数n(1<=n<=200000),接下来n个整数(每个整数都是小于10的9次方的非负整数),接下来有不超过200000的操作,以END结束
Output
对于每一个M操作,输出x到y的和
Sample Input
3 1 2 3 M 1 3 S 2 6 M 1 3 END
Sample Output
6 10