敌兵布阵(线段树-单点修改)

敌兵布阵(线段树-单点修改)_第1张图片
敌兵布阵(线段树-单点修改)_第2张图片
敌兵布阵(线段树-单点修改)_第3张图片

#include
#include
#include
#include
using namespace std;
#define lson 2*k,l,mid
#define rson 2*k+1,mid+1,r
const int MAXN = 1e5;
int num[MAXN], sum[MAXN*4]; 		//要开4倍数组 
//num  数组记录第i个营地一开始有多少人  
//sum  数组记录变化后营地的总人数 
void BuildTree(int k,int l,int r)
{
	if(l == r)
	{
		sum[k] = num[l];
		return ;
	}
	int mid = (l+r)/2;
	BuildTree(lson);		//递归建立左子树和右子树
	BuildTree(rson);
	sum[k] = sum[2*k] + sum[2*k+1];
}
void add(int k,int l,int r,int ql,int res)
{
	if(l == r)
	{
		sum[k]+=res;
		return ;
	}
	int mid=(r+l)/2;
	if(ql <= mid)
	{
		add(lson,ql,res);
	}
	else
	{
		add(rson,ql,res);
	}
	sum[k] = sum[2*k] + sum[2*k+1];
}
void sub(int k,int l,int r,int ql,int res)
{
	if(l == r)
	{
		sum[k]-=res;
		return ;
	}
	int mid=(r+l)/2;
	if(ql <= mid)
	{
		sub(lson,ql,res);
	}
	else
	{
		sub(rson,ql,res);
	}
	sum[k] = sum[2*k] + sum[2*k+1];
}
int query(int k,int l,int r,int ql,int qr)
{
	if(ql>r || qr<l)	//区域外 
	{
		return 0;
	}
	else if(ql<=l && r<=qr)	//区域内 
	{
		return sum[k];
	}
	int mid=(l+r)/2;
	int sum1=query(lson,ql,qr);
	int sum2=query(rson,ql,qr);
	return sum1+sum2;
}
int main()
{
	int T,n;
	scanf("%d",&T);
	int k = 1;
	char s[10];
	while( T-- )
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&num[i]);
		}
		BuildTree(1,1,n);	//参数 k l r,k和l必为1,右边界r为n
		printf("Case %d:\n",k);
		while(~scanf("%s",s)){
			if(!strcmp(s,"End")){
				break;
			}
			int x,y;
			scanf("%d%d",&x,&y);
			if(!strcmp(s,"Query")){
				printf("%d\n",query(1,1,n,x,y));
			}
			else if(!strcmp(s,"Add")){
				add(1,1,n,x,y);
			}
			else{
				sub(1,1,n,x,y);
			}
		}
		k++;
	}
	return 0;
 } 

你可能感兴趣的:(线段树)