线段树(hdu1166)

敌人有N个工兵营地,接下来有N个正整数,第i个正整数ai代表第i个工兵营地里开始时有ai个人(1<=ai<=50)。
接下来每行有一条命令,命令有4种形式:
(1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30)
(2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30);
(3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数;
(4)End 表示结束,这条命令在每组数据最后出现;
不知道是不是后台太松了,我受以前某道题启发,然后不用线段树卡过了哈哈哈
先存一下我的卡bug代码:

#include <stdio.h>
 #include <string.h>
 #include <algorithm>
 using namespace std;
 int a[51000],he[51000];
 int main()
 {
 	int t,n,i,j,flag=0;
 	scanf("%d",&t);
 	while(t--)
 	{
 		flag++;
 		printf("Case %d:
",flag);
 		memset(a,0,sizeof(a));
 		scanf("%d",&n);
 		a[0]=0;
 		for (i=1; i<=n; i++)
 		{
 			scanf("%d",&a[i]);
 			he[i]=a[i]+he[i-1];
 		}
 
 		char c[110];
 		int t1,t2;
 
 		while(~scanf("%s",c)&&strcmp(c,"End")!=0)
 		{
 
 			if (!strcmp(c,"Add"))
 			{
 				scanf("%d%d",&t1,&t2);
 
 				for (i=t1; i<=n; i++)
 					he[i]+=t2;
 			}
 			if (!strcmp(c,"Sub"))
 			{
 				scanf("%d%d",&t1,&t2);
 
 				for (i=t1; i<=n; i++)
 					he[i]-=t2;
 			
 			}
 			if (!strcmp(c,"Query"))
 			{
 				int sum=0;
 				scanf("%d%d",&t1,&t2);
 				sum=he[t2]-he[t1-1];
 				printf("%d
",sum);
 			}
 		}
 	}
 	return 0;
 }
用线段树做就是一个模板:
上一个结构体的线段树:
`
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
int a[5000000];
struct node
{
 int l,r;
 int sum;
} b[150005];
void Build(int l,int r,int i)
{
 b[i].l=l;
 b[i].r=r;
 if(l==r)
 {
 	b[i].sum=a[l];
 	return ;//
 }
 int mid=(l+r)/2;
 Build(l,mid,x<<1);//递归建立左子树
 Build(mid+1,r,x<<1|1);//递归建立右子树
 b[x].sum=b[x<<1].sum+b[x<<1|1].sum;//记录该结点左右子树的值
}

void Add(int j,int num,int x)
{
 if(b[x].l==b[i].r) //到达叶子结点
 {
 	b[x].sum+=num;
 	return ;//
 }
 else
 {
 	b[x].sum+=num;//所有父节点都增加
 	if(j<=b[x<<1].r)
 		Add(j,num,x<<1);
 	else Add(j,num,x<<1|1);
 }
}

int Query(int l,int r,int x)
{
 if(b[x].l==l&&b[x].r==r)
 	return b[x].sum;
 int mid=(b[x].l+b[x].r)>>1;//应该是>>1表示/2
 if(r<=mid)
 	return Query(l,r,x<<1);
 else if(l>mid)
 	return Query(l,r,x<<1|1);
 else return
 	    Query(l,mid,x<<1)+Query(mid+1,r,x<<1|1);
}
int main()
{
 int t,k=0,i,j,num,n;
 char s[10];
 scanf("%d",&t);
 while(t--)
 {
 	scanf("%d",&n);
 	for(i=1; i<=n; i++)
 	{
 		scanf("%d",&a[i]);
 	}
 	
 	Build(1,n,1);
 	while(1)
 	{
 		scanf("%s",s);
 		scanf("%d%d",&j,&num);
 		if(!strcmp(s,"Query"))
 		{
 			printf("Case %d:
",++k);
 		}	printf("%d
",Query(j,num,1));
 		if(!strcmp(s,"Add"))
 			Add(j,num,1);
 		if(!strcmp(s,"Sub"))
 			Add(j,-num,1);
 		if(!strcmp(s,"End"))
 			break;
 	}
 }
 return 0;
}`
原文地址:https://www.cnblogs.com/shidianshixuan/p/13729810.html