HDU 1166 敌兵布阵 [线段树-单点更新]

题意:


分析:


//AC CODE:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 300000
#define BUF_SIZE 50
#define L 0
#define R 1
#define SUM 2

long seg[MAXSIZE][3];

void build(long r,long x1,long x2)
{
    seg[r][L]=x1;
    seg[r][R]=x2;
    seg[r][SUM]=0;
    if(x1==x2)
        return ;
    else
    {
        long mid=(x1+x2)>>1;
        build(r<<1,x1,mid);
        build((r<<1)+1,mid+1,x2);
    }
}

void add(long id,long n)
{
    long x1,x2,mid,r;

    r=1;
    x1=seg[r][L];
    x2=seg[r][R];
    mid=(x1+x2)>>1;

    while(x2!=x1)
    {
        seg[r][SUM]+=n;
        if(id<=mid)
            r<<=1;//left
        else
            r=(r<<1)+1;//right
        x1=seg[r][L];
        x2=seg[r][R];
        mid=(x1+x2)>>1;
    }
    seg[r][SUM]+=n;
}

long query(long r,long x1,long x2)
{
    long left=seg[r][L],right=seg[r][R],mid=(left+right)>>1;

    if(x1==left&&x2==right)
        return seg[r][SUM];
    else if(x2<=mid)
        return query(r<<1,x1,x2);
    else if(x1>mid)
        return query((r<<1)+1,x1,x2);
    else
        return query(r<<1,x1,mid)+query((r<<1)+1,mid+1,x2);
}

int main()
{
    int ncase,ccase=0;
    long N,i,j;
    char buf[BUF_SIZE];

    scanf("%d",&ncase);
    while(ncase--)
    {
        printf("Case %d:\n",++ccase);

        scanf("%ld",&N);
        build(1,1,N);
        for(i=1; i<=N; i++)
        {
            scanf("%ld",&j);
            add(i,j);
        }
        while(scanf("%s",buf),*buf!='E')
        {
            scanf("%ld%ld",&i,&j);
            if(*buf=='A')
                add(i,j);
            else if(*buf=='S')
                add(i,-j);
            else
                printf("%ld\n",query(1,i,j));
        }
    }
    return 0;
}

大牛的代码(可供学习,稍微得修改了一下):

#include <cstdio>

using namespace std;

const int maxn = 55555;
int sum[maxn<<2];

void PushUP(int rt)
{
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if (l == r)
    {
        scanf("%d",&sum[rt]);
        return ;
    }
    int m = (l + r) >> 1;
    build(l , m , rt << 1);
    build(m + 1 , r , rt << 1 | 1);
    PushUP(rt);
}

void update(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)
        update(p , add , l , m , rt << 1);
    else
        update(p , add , m + 1 , r , rt << 1 | 1);
    PushUP(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if (L <= l && r <= R)
    {
        return sum[rt];
    }
    int m = (l + r) >> 1;
    int ret = 0;
    if (L <= m)
        ret += query(L , R , l , m , rt << 1);
    if (R > m)
        ret += query(L , R , m + 1 , r , rt << 1 | 1);
    return ret;
}

int main()
{
    int T , n;
    scanf("%d",&T);
    for (int cas = 1 ; cas <= T ; cas ++)
    {
        printf("Case %d:\n",cas);
        scanf("%d",&n);
        build(1 , n , 1);
        char op[10];
        while (scanf("%s",op))
        {
            if (op[0] == 'E')
                break;
            int a , b;
            scanf("%d%d",&a,&b);
            if (op[0] == 'Q')
                printf("%d\n",query(a , b , 1 , n , 1));
            else if (op[0] == 'S')
                update(a , -b , 1 , n , 1);
            else
                update(a , b , 1 , n , 1);
        }
    }
    return 0;
}


你可能感兴趣的:(HDU 1166 敌兵布阵 [线段树-单点更新])