hdu 1166 敌兵布阵 (线段树初步)

本文详细介绍了如何使用线段树解决区间求和及元素更新问题。通过实例代码讲解了线段树的构建、更新和查询操作,适用于初学者快速掌握线段树的基本应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目分析:给定n个数,对某个数进行修改,对于某个区间内的数求和,最基本的线段树


代码:

#include<iostream>
#include<cstdio>
#include<memory.h>
using namespace std;

struct line 
{
	int left,right;
	int no;
	int value;
}a[1000100];

void build(int s,int t,int n)
{
	int mid=(s+t)/2;
	a[n].left=s;
	a[n].right=t;
	if(s==t)
	{
		return ;
	}
	build(s,mid,2*n);
	build(mid+1,t,2*n+1);
}
void UpDate(int T,int L,int R,int LL,int value )
{
	if(L==LL&&R==LL)
	{
		//printf("T=%d   //////\n",T);
		a[T].value+=value;
		return ;//开始时丢了
	}
	int mid=(L+R)/2;
	if(LL<=mid)
	   UpDate(T*2,L,mid,LL,value);
	else
	   UpDate(T*2+1,mid+1,R,LL,value);

	a[T].value=a[T*2].value+a[T*2+1].value;
}
int query(int T,int L,int R,int LL,int RR)
{
   if(L==LL&&R==RR)
	   return a[T].value;
 
   int mid=(L+R)/2;
   if(RR<=mid)
	   return query(T*2,L,mid,LL,RR);
   if(LL>mid)//if(LL>=mid)...错过一回了
	   return query(T*2+1,mid+1,R,LL,RR);
   int left=query(T*2,L,mid,LL,mid);
   int right=query(T*2+1,mid+1,R,mid+1,RR);

   return left+right;
}
int convert(char s[])
{
	int temp=0;
	int len=strlen(s);
	for(int i=0;i<len;i++)
		temp=temp*10+(s[i]-'0');
	return temp;
}
int main()
{
	int T;
	scanf("%d",&T);
	for(int t=1;t<=T;t++)
	{
		printf("Case %d:\n",t);
		int n,temp;
		scanf("%d",&n);
		memset(a,0,sizeof(a));
		build(1,n,1);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&temp);
			UpDate(1,1,n,i,temp);
		}
		getchar();
		char s[100];
		while(1)
		{
			int x,y;
			char s1[100];
			gets(s);
			if(s[0]=='Q')
			{
				int k=6,i=0;
                while(s[k]!=' ')
				{
                   s1[i++]=s[k++];
				}
				s1[i]='\0';
				x=convert(s1);
				k++,i=0;
				while(s[k]!='\0')//while(k!='\0'),脑残了,
				{
                   s1[i++]=s[k++];   
				}
				s1[i]='\0';
				y=convert(s1);

				int ans=query(1,1,n,x,y);
				printf("%d\n",ans);
			}
			else if(s[0]=='A')
			{
				int k=4,i=0;
                while(s[k]!=' ')
				{
                   s1[i++]=s[k++];
				}
				s1[i]='\0';
				x=convert(s1);
				k++,i=0;
				while(s[k]!='\0')
				{
                   s1[i++]=s[k++];   
				}
				s1[i]='\0';
				y=convert(s1);
               // printf("x=%d  y=%d\n",x,y);
				UpDate(1,1,n,x,y);
			}
			else if(s[0]=='S')
			{
				int k=4,i=0;
                while(s[k]!=' ')
				{
                   s1[i++]=s[k++];
				}
				s1[i]='\0';
				x=convert(s1);
				k++,i=0;
				while(s[k]!='\0')
				{
                   s1[i++]=s[k++];   
				}
				s1[i]='\0';
				y=convert(s1);
				//printf("x=%d y=%d\n",x,y);
				UpDate(1,1,n,x,-y);
			}
			else
				break;
		}
	}
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值