Hdu 1166 排兵布阵

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166

最基础的线段树问题。

单点更新,区间查找。

本题可以用树状数组做,但是线段树除了处理区间求和问题外,还可以处理区间极值问题,所以虽然ZKW树状数组可以取代线段树的求和部分,但是并不能却带线段树在其他领域的功用。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;

#define Maxn 50005
#define lx (x<<1)
#define rx (x<<1 | 1)
#define MID ((l + r)>>1)

int A[Maxn];
int S[Maxn<<2];

void pushUp(int x)
{
    S[x] = S[lx] + S[rx];
}
void build(int l,int r,int x)
{
    if(l == r)
    {
        S[x] = A[l];
        return;
    }
    build(l,MID,lx);
    build(MID+1,r,rx);
    pushUp(x);
}

int query(int L,int R,int l,int r,int x)
{
    if(L<=l && r<=R) return S[x];
    int ans = 0;
    if(L<=MID) ans += query(L,R,l,MID,lx);
    if(MID<R) ans += query(L,R,MID+1,r,rx);
    return ans;
}
void update(int p,int d,int l,int r,int x)
{
    if(l == r)
    {
        S[x] += d;
        return;
    }
    if(p <= MID) update(p,d,l,MID,lx);
    else update(p,d,MID+1,r,rx);
    pushUp(x);
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    int t;
    int n;
    char cmd[10];
    int cas = 0;
    int a,b;
    scanf(" %d",&t);
    while(t--)
    {
        cas++;
        printf("Case %d:\n",cas);
        scanf(" %d",&n);
        for(int i=1;i<=n;i++) scanf(" %d",&A[i]);
        build(1,n,1);
        while(scanf(" %s",cmd)!=EOF && cmd[0]!='E')
        {
            scanf(" %d %d",&a,&b);
            if(cmd[0] == 'Q') printf("%d\n",query(a,b,1,n,1));
            else if(cmd[0] == 'S') update(a,-b,1,n,1);
            else if(cmd[0] == 'A') update(a,b,1,n,1);
        }
    }
    return 0;
}


你可能感兴趣的:(Hdu 1166 排兵布阵)