hdu1166 敌兵布阵 线段树入门

渣渣做的线段树入门的题

题目地址:hdu1166 敌兵布阵

#include<iostream>
#include<cstdio>
using namespace std;
const int N = 50000+10;
int a[N],p;//p是指向数组a的指针,每次新的数据记得初始化
int s_tree[3*N];//每个结点只存储工兵数量的和
void buit(int l,int r,int num){
	if(l==r)	{s_tree[num] = a[p++];return;}
	
	int mid = (l+r)/2;
	buit(l,mid,num*2);
	buit(mid+1,r,num*2+1);
	s_tree[num] = s_tree[num*2]+s_tree[num*2+1];

}

int Query(int i,int j,int l,int r,int num){
	int mid = (l+r)/2;
	if(i==l&&j==r)	return s_tree[num];
	else if(j<=mid){
		return Query(i,j,l,mid,num*2);
	}
	else if(i>mid){
		return Query(i,j,mid+1,r,num*2+1);
	}
	else{
		return Query(i,mid,l,mid,num*2)+Query(mid+1,j,mid+1,r,num*2+1);
	}
}

void Add(int i,int j,int l,int r,int num){
	if(i==l&&l==r){
		s_tree[num]+=j;
		return ;
	}
	s_tree[num]+=j;
	int mid = (l+r)/2;
	if(i<=mid)	Add(i,j,l,mid,num*2);
	else Add(i,j,mid+1,r,num*2+1);
}

void Sub(int i,int j,int l,int r,int num){
	if(i==l&&l==r){
		s_tree[num]-=j;
		return ;
	}
	s_tree[num]-=j;
	int mid = (l+r)/2;
	if(i<=mid)	Sub(i,j,l,mid,num*2);
	else	Sub(i,j,mid+1,r,num*2+1);
}


int main(){
	int T,N;
	int i,j;
	int w = 1;
	char str[10];
	cin>>T;
	while(T--){
		cin>>N;
		p = 0;
		for(int k=0;k<N;k++){
			scanf("%d",&a[k]);
		}
		buit(1,N,1);
		str[0] = 'B';
		//cout<<"Case "<<w++<<":"<<endl;
		printf("Case %d:\n",w++);
		while(true){
			//cin>>str;
			scanf("%s",str);
			if(str[0]=='E')	break;
			//cin>>i>>j;
			scanf("%d%d",&i,&j);
			if(str[0]=='Q'){
				printf("%d\n",Query(i,j,1,N,1));
			}	
			else if(str[0]=='A')	Add(i,j,1,N,1);
			else if(str[0]=='S')	Sub(i,j,1,N,1);
		}

	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/l_apple8/article/details/50570952