线段树的的基本操作(敌兵布阵)
例题:敌兵布阵
题目链接
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;;
int mp[2*N];
int tree[2*N];
int n;
void build_tree(int l,int r,int node)//建树
{
if(l==r)
{
tree[node]=mp[l];
}
else
{
int mid=(l+r)/2;
build_tree(l,mid,2*node);
build_tree(mid+1,r,2*node+1);
tree[node]=tree[node*2]+tree[node*2+1];
}
}
int query(int a,int b,int node,int l,int r)//区间和
{
if(a>r||b<l) return 0;
else if(l==r) return tree[node];
else if(l>=a&&r<=b) return tree[node];
else
{
int mid=(l+r)/2;
int lsum=query(a,b,2*node,l,mid);
int rsum=query(a,b,2*node+1,mid+1,r);
return lsum+rsum;
}
}
void update(int idx,int val,int node,int l,int r)//点修改
{
if(l==r)
{
tree[node]+=val;
mp[idx]=val;
}
else
{
int mid=(l+r)/2;
if(idx>=l&&idx<=mid)
{
update(idx,val,2*node,l,mid);
}
else
{
update(idx,val,2*node+1,mid+1,r);
}
//tree[node]+=val;
tree[node]=tree[node*2]+tree[node*2+1];
}
}
int main()
{
int t;
scanf("%d",&t);
int k=0;
while(t--)
{
printf("Case %d:\n",++k);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&mp[i]);
memset(tree,0,sizeof tree);
build_tree(1,n,1);
char s[10];
while(scanf("%s",s))
{
int a,b;
if(s[0]=='E') break;
scanf("%d %d",&a,&b);
if(s[0]=='Q')
{
int t=query(a,b,1,1,n);
printf("%d\n",t);
}
else if(s[0]=='A')
{
update(a,b,1,1,n);
}
else if(s[0]=='S')
{
update(a,-1*b,1,1,n);
}
}
}
return 0;
}