首页 > 代码库 > NYOJ 116 士兵杀敌(二)【线段树 单点更新】

NYOJ 116 士兵杀敌(二)【线段树 单点更新】

题意:题意很清楚;

策略;如题。

这道题就是简单的线段树应用,据说还可以用树状数组来做,等我学了之后在说吧。

代码:

#include<stdio.h>
#include<string.h>
#define LC l, m, rt<<1
#define RC m+1, r, rt<<1|1
#define LL long long
#define MAXN 1000000
LL sum[MAXN<<2];
void PushUp(int rt)
{
	sum[rt] = sum[rt<<1]+sum[rt<<1|1];
}
void creat(int l, int r, int rt)
{
	if(l == r){
		scanf("%lld", &sum[rt]);
		return;
	}
	int m = (l+r)>>1;
	creat(LC);
	creat(RC);
	PushUp(rt);
}
void update(int p, int num, int l, int r, int rt)
{
	if(l == r){
		sum[rt] += (LL)num;
		return;
	}
	int m = (l+r)>>1;
	if(p <= m) update(p, num, LC);
	else update(p, num, RC);
	PushUp(rt);
}
LL query(int ll, int rr, int l, int r, int rt)
{
	if(ll <= l&&r<= rr){
		return sum[rt];
	}
	LL res = 0;
	int m = (l+r)>>1;
	if(ll <= m) res += query(ll, rr, LC);
	if(rr > m) res += query(ll, rr, RC);
	return res;
}
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	creat(1, n, 1);
	char s[10];
	int a, b;
	while(m -- ){
		scanf("%s", s);
		if(s[0] == 'Q'){
			scanf("%d%d", &a, &b);
			printf("%lld\n", query(a, b, 1, n, 1));
		}
		else{
			scanf("%d%d", &a, &b);
			update(a, b, 1, n, 1);
		}
	}
	return 0;
}

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=116