hdu 1166 敌兵布阵

线段树查询和更新的一道简单题,注意右移>> 和左移<<运算的优先级 (它们的优先级比 + 、- 还低),另外就是处理输入输出时不要使用cin、cout。

代码:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>

using namespace std;

const int maxn = 50000 + 10;
int tree[maxn * 4];			//线段树,除过叶节点外,其余为所对应区间总人数
int casenum;
int N;			//N个工兵阵地
int peo[maxn];		//工兵阵地人数
char str[30];

void build_tree(int node,int lp,int rp)		//结点node 所对应区间[lp,rp]
{
	if (lp == rp)
		tree[node] = peo[lp];
	else
	{
		int mid = (lp + rp) >> 1;
		build_tree(node << 1, lp, mid);
		build_tree((node << 1) + 1, mid + 1, rp);

		tree[node] = tree[node << 1] + tree[(node << 1) + 1];
	}
}


//向结点 node 区间[lp,rp]增加army val,
void add_peo(int node, int lp, int rp,int army,int val)
{
	//army 在区间[lp,rp]之外
	if (army < lp || army > rp)
		return;
	else if (lp == rp && lp == army)
	{
		tree[node] += val;
		return;
	}

	tree[node] += val;
	int mid = (lp + rp) >> 1;
	add_peo(node << 1, lp, mid, army, val);
	add_peo((node << 1) + 1, mid + 1, rp, army, val);
}
//
//void sub_peo(int node, int lp, int rp, int army, int val)
//{
//	if (army < lp || army > rp)
//		return;
//	else if (lp == rp && lp == army)
//	{
//		tree[node] -= val;
//		return;
//	}
//
//	tree[node] -= val;
//	int mid = (lp + rp) / 2;
//	sub_peo(node * 2, lp, mid, army, val);
//	sub_peo(node * 2 + 1, mid + 1, rp, army, val);
//}

int query(int node, int tl, int tr, int lp, int rp)
{
	//如果 【lp,rp】 与区间[tl,tr]无任何交集
	if (tr < lp || tl > rp)
		return 0;
	//如果 [lp,rp]在区间 [tl,tr]范围内
	if (tl <= lp && rp <= tr)
		return tree[node];

	int mid = (lp + rp) >> 1;
	return query(node << 1, tl, tr, lp, mid) +
		query((node <<1) + 1, tl, tr, mid + 1, rp);
}

int main()
{
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
	int m, n,index = 1;			//指令后面的数字
	//cin >> casenum;
	scanf("%d", &casenum);
	while (casenum--)
	{
		//cin >> N;
		scanf("%d", &N);
		for (int i = 1; i <= N; i++)
		{
			//cin >> peo[i];
			scanf("%d",&peo[i]);
		}
		//cout << "Case " << index++ << ":" << endl;
		printf("Case %d:\n", index++);
		build_tree(1, 1, N);
		//cin >> str;
		scanf("%s", str);
		while ('E' != str[0])
		{
			scanf("%d %d", &m, &n);
			if ('Q' == str[0])
			{
				printf("%d\n", query(1, m, n, 1, N));
			}
			else if ('A' == str[0])
				add_peo(1, 1, N, m, n);
			else
				add_peo(1, 1, N, m, -n);
			scanf("%s", str);
		}//while end
	}//while casenum

	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值