hdu 1166 敌兵布阵 (线段树、树状数组模板,单点更新)

hdu 1166


方法1:线段树

#include <iostream>
#include<algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 55555;
struct node{
	int l, r;
	int val;
};
int a[MAXN];
node T[MAXN * 4 + 10];
void build(int rt, int begin, int end) {
	if(begin == end) {
		T[rt].val = a[begin];
		T[rt].l = begin;
		T[rt].r = end;
	}
	else {
		int mid = (begin + end) >> 1;
		build(rt << 1, begin, mid);
		build(rt << 1 | 1, mid + 1, end);
		T[rt].val = T[rt << 1].val + T[rt << 1 | 1].val;
		T[rt].l = begin;
		T[rt].r = end;
	}
}
void updata(int rt, int id, int add) {
	if(T[rt].l == T[rt].r) {
		T[rt].val += add;
	}
	else {
		int mid = (T[rt].l + T[rt].r) >> 1;
		if(id <= mid) updata(rt << 1, id, add);
		else updata(rt << 1 | 1, id, add);
		T[rt].val = T[rt << 1].val + T[rt << 1 | 1].val;
	}
}
int query(int rt, int l, int r) {
	if(T[rt].l >= l && T[rt].r <= r) {
		return T[rt].val;
	}
	else {
		int mid = (T[rt].l + T[rt].r) >> 1;
		if(r <= mid) return query(rt << 1, l, r);
		else if(l > mid) return query(rt << 1 | 1, l, r);
		else return query(rt << 1, l, mid) + query(rt << 1 | 1, mid + 1, r);
	}
}
int main() {
	//freopen("input.txt", "r", stdin);
	int T;
	scanf("%d", &T);
	int N;
	int j;
	for(j = 1; j <= T; j++) {
		printf("Case %d:\n", j);
		scanf("%d", &N);
		int i;
		for(i = 1; i <= N; i++) {
			scanf("%d", a + i);
		}
		build(1, 1, N);
    	char str[10];
    	int x, y;
    	while(1) {
    		scanf("%s", str);
    		if(str[0] == 'E') break;    //此处注意runtime error 
    		scanf("%d %d", &x, &y);
    		if(str[0] == 'Q') {
    			printf("%d\n", query(1, x, y));
			}
			else if(str[0] == 'A') {
				updata(1, x, y);
			}
			else {
				updata(1, x, -y);
			}
		}
	}
    return 0;
}

方法2: 树状数组

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 50005;
int sum[maxn], N;
int lowbit(int x) {
	return x & (-x);
}
void update(int index, int val) {
	int i;
	for(i = index; i <= N; i += lowbit(i)) {
		sum[i] += val;
	}
}
int getsum(int index) {
	int i;
	int res = 0;
	for(i = index; i > 0; i -= lowbit(i)) {
		res += sum[i];
	}
	return res;
}
int main() {
	int T;
	int kase = 1;
	scanf("%d", &T);
	while(T--) {
		printf("Case %d:\n", kase++);
		scanf("%d", &N);
		memset(sum, 0, sizeof(sum));
		int i, tmp;
		for(i = 1; i <= N; i++) {
			scanf("%d", &tmp);
			update(i, tmp);
		}
		string str;
		int n, m;
		while (cin >> str) {
      		if (str == "End") break;
     			scanf("%d%d", &n, &m);
      		if (str == "Query")
        		printf("%d\n", getsum(m) - getsum(n - 1));
      		else if (str == "Add")
        		update(n, m);
      		else update(n, -m);
    	}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值