线段树

线段树(补)

这个东西是真的难懂,具体的可以去看别的详细的博客学习。这里只上个例题。
例:HDU - 1166 (http://acm.hdu.edu.cn/showproblem.php?pid=1166)

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
#pragma warning(disable:4996)
using namespace std;
const int MAXN = 1e5 + 10;
const int inf = 0x3f3f3f3f;
const int N = 50010;
int a[N];
struct segmenttree {
	int l;
	int r;
	int sum;
}h[N<<2];
void pushup(int i) {
	h[i].sum = h[i << 1].sum + h[i << 1 | 1].sum;
}
void build(int l,int r,int i) {
	h[i].l = l;
	h[i].r = r;
	if (l == r) {
		h[i].sum = a[l];
		return;
	}
	int mid = l + r >> 1;
	build(l, mid, i << 1);
	build(mid+1, r, i << 1 | 1);
	pushup(i);
}
void modify(int p, int w, int i) {
	if (h[i].l == p && h[i].r == p) {
		h[i].sum += w;
		return;
	}
	int mid = h[i].l + h[i].r >> 1;
	if (p <= mid)modify(p, w, i << 1);
	else modify(p, w, i << 1 | 1);
	pushup(i);
}
int query(int l, int r, int i) {
	if (l <= h[i].l && r >= h[i].r) {
		return h[i].sum;
	}
	int mid = h[i].l + h[i].r >> 1;
	int res=0;
	if (l <= mid) res += query(l, r, i << 1);
	if (r > mid) res += query(l, r, i << 1 | 1);
	return res;
}
int main() {
	int t,n,k=1;
	char s[10];
	scanf("%d", & t);
	while (t--) {
		printf("Case %d:\n", k);
		k++;
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) {
			scanf("%d", &a[i]);
		}
		build(1, n, 1);
		int x, y;
		while (~scanf("%s",s)) {
			if (!strcmp(s, "End"))break;
			scanf("%d %d", &x, &y);
			if (!strcmp(s, "Add")) {
				modify(x, y, 1);
			}
			else if (!strcmp(s, "Sub")) {
				modify(x, -y, 1);
			}
			else if (!strcmp(s, "Query")) {
				printf("%d\n", query(x, y, 1));
			}
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值