hdu 1166 线段树 (初步)

本文介绍了一种数据结构——区间树的实现方法及其在解决特定问题中的应用。通过具体实例展示了如何建立区间树,并实现增删改查等操作,特别关注了区间查询的功能。

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

/*
    Subject: Interval Tree
    Author : a_clay
    Created Date : 2012-02-03
    Sample : hdoj 1166 敌兵布阵 很基础,很赤裸,但也很经典
*/
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define Bug cout << "here\n";
#define B(x) (x >> 1)
using namespace std;
const int N = 50005;

int r[N];
struct node {
	int a, b;
	int sum;
}t[3*N];
int SUM = 0;
void make_tree(int x, int y, int num) { // 建树
	t[num].a = x;
	t[num].b = y;
	if(x == y) t[num].sum = r[y];
	else {
		make_tree(x, B(x+y), 2*num);
		make_tree(B(x+y)+1, y, 2*num+1);
		t[num].sum = t[2*num].sum + t[2*num+1].sum;
	}
}
void add(int x, int ren, int num) {
	t[num].sum += ren;
	if(x == t[num].a && x == t[num].b) return;
	int mid = B(t[num].a + t[num].b);
	if(x <= mid) {
		add(x, ren, 2*num);
	}
	else add(x, ren, 2*num+1);
}
void query(int x, int y, int num) {
	int mid = B(t[num].a + t[num].b);
	if(x <= t[num].a && t[num].b <= y) { // 找终止区间
		SUM += t[num].sum;
	}
	else {
		if(y <= mid) {
			query(x, y, 2*num);
		}
		else if(x > mid) {
			query(x, y, 2*num+1);
		}
		else {
			query(x, y, 2*num);
			query(x, y, 2*num+1);
		}
	}
}

int main() {
	int e = 0, T, n, i;
	scanf("%d", &T);
	while(T--) {
		memset(r, 0, sizeof(r));
		memset(t, 0, sizeof(t));
		cout << "Case " << ++e << ':' << endl;
		scanf("%d", &n);
		for(i = 1; i <= n; i++) {
			scanf("%d", &r[i]);
		}
		make_tree(1, n, 1);
        char str[10];
        int a, b;
        while(cin >> str) {
            if(str[0] == 'E') {
                break;
            }
            else if(str[0] == 'A') {
                cin >> a >> b;
                add(a, b, 1);
            }
            else if(str[0] == 'S') {
                cin >> a >> b;
                add(a, (-b), 1);
            }
            else if(str[0] == 'Q') {
                cin >> a >> b;
                SUM = 0;
                query(a, b, 1);
                cout << SUM << endl;
            }
        }
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值