题目链接
题目意思
给定一个序列,有三种操作,最后输出给定范围的值之和
题目意思
数据大,普通方法肯定超时,用线段树来计算区间的加法。
代码部分
#include <iostream>
#include <stdio.h>
#include <string.h>
#define lchild left,mid,root<<1
#define rchild mid+1,right,root<<1|1
using namespace std;
const int maxn=50005;
int sum[maxn<<2];
int n;
///更新线段树节点
void push_up(int root)
{
sum[root]=sum[root<<1]+sum[root<<1|1];
}
///构造线段树
void build(int left,int right,int root)
{
if(left==right)
{
int num;
scanf("%d",&num);
sum[root]=num;
return;
}
int mid=(left+right)>>1;
build(lchild);
build(rchild);
push_up(root);
}
///更改操作
void updata(int aim,int num,int left,int right,int root)
{
if(left==right)
{
sum[root]+=num;
return;
}
int mid=(left+right)>>1;
if(mid>=aim)
updata(aim,num,lchild);
else
updata(aim,num,rchild);
push_up(root);
}
///查询操作
int query(int L,int R,int left,int right,int root)
{
if(L<=left&&right<=R)
{
return sum[root];
}
int ans=0;
int mid=(left+right)>>1;
if(R<=mid)
ans+=query(L,R,lchild);
else if(L>mid)
ans+=query(L,R,rchild);
else
{
ans+=query(L,R,lchild);
ans+=query(L,R,rchild);
}
return ans;
}
int main()
{
int t,temp=1;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
build(1,n,1);
string s;
cout<<"Case "<<temp++<<":"<<endl;
while(cin>>s)
{
int n1,n2;
if(s[0]=='E')
break;
if(s[0]=='Q')
{
scanf("%d%d",&n1,&n2);
int ans=query(n1,n2,1,n,1);
cout<<ans<<endl;
}
if(s[0]=='A')
{
scanf("%d%d",&n1,&n2);
updata(n1,n2,1,n,1);
}
if(s[0]=='S')
{
scanf("%d%d",&n1,&n2);
updata(n1,-n2,1,n,1);
}
}
}
return 0;
}