1. 程式人生 > >hdu 1116 敵兵布陣 線段樹 區間求和 單點更新

hdu 1116 敵兵布陣 線段樹 區間求和 單點更新

freopen names 區間求和 add 知識 scan urn code blog

線段樹的基本知識可以先google一下,不是很難理解

線段樹功能:update:單點增減 query:區間求和

#include <bits/stdc++.h>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;

const int MAXN = 50008;
int sum[MAXN<<2];

void build(int l, int r, int rt)
{
    if(l == r)
    {
        scanf(
"%d", &sum[rt]); return; } int m = (l + r) >> 1; build(lson); build(rson); sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } int query(int L, int R, int l, int r, int rt) { if(L <= l && r <= R) return sum[rt]; int ret = 0;
int m = (l + r) >> 1; if(L <= m) ret += query(L, R, lson); if(R > m) ret += query(L, R, rson); return ret; } void updata(int p, int add, int l, int r, int rt) { if(l == r) { sum[rt] += add; return; } int m = (l + r) >> 1;
if(p <= m) updata(p, add, lson); else updata(p, add, rson); sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } int main() { // freopen("in.txt", "r", stdin); int T, Case = 0; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); build(1, n, 1); printf("Case %d:\n", ++Case); char s[10]; while(~scanf("%s", s)) { if(s[0] == E) break; int a,b; scanf("%d%d", &a, &b); if(s[0] == Q) printf("%d\n", query(a, b, 1, n, 1)); else if(s[0] == A) updata(a, b, 1, n, 1); else updata(a, -b, 1, n, 1); } } return 0; }

hdu 1116 敵兵布陣 線段樹 區間求和 單點更新