基础线段树问题
题意:n个阵营,每个阵营人数都有个初始值,接着有好多个指令(直到指令为'End'为止)Add指令第i位置加j个人,Sub指令为第i个位置减j个人,Query指令为询问【i,j】区间总人数。
分析:直接用线段树(线段树模板题)
给代码:
#include<iostream>
using namespace std;
int node[200005];
void buildtree(int i,int l,int r)
{
if(l==r)
{
cin>>node[i];
return;
}
int mid=(l+r)/2;
buildtree(i*2,l,mid);
buildtree(i*2+1,mid+1,r);
node[i] =node[i*2] +node[i*2+1];
}
int query(int i,int l,int r,int x,int y)
{//[x,y]区间包含[l,r]区间时才有效,才能取
if(x<=l&&y>=r) return node[i];
int ans=0;
int mid=(l+r)/2;
if(x<=mid) ans+=query(i*2,l,mid,x,y);
if(y>mid) ans+=query(i*2+1,mid+1,r,x,y);
return ans;
}
void updata(int i,int l,int r,int x,int y)
{
if(l==r)
{
node[i]+=y;
return;
}
int mid=(l+r)/2;
if(x<=mid) updata(i*2,l,mid,x,y);//敲重点,判断的是区间点,而不是树内的节点 之前一直错的是if(i<=mid) updata(i*2,l,mid,x,y);
else updata(i*2+1,mid+1,r,x,y);
node[i]=node[i*2]+node[i*2+1];
}
int main()
{
int T;
cin>>T;
for(int num=1;num<=T;num++)
{
cout<<"Case "<<num<<':'<<endl;
int n;
cin>>n;
buildtree(1,1,n);
char s[10];
int x,y;
while(cin>>s)
{
if(s[0]=='E') break;
cin>>x>>y;
if(s[0]=='Q') cout<<query(1,1,n,x,y)<<endl;
else if(s[0]=='A') updata(1,1,n,x,y);
else if(s[0]=='S') updata(1,1,n,x,-y);
}
}
return 0;
}