HDU 1166 敌兵布阵(第一个线段树)

题目链接

这个题,用完树状数组,再用线段树水过。线段树,却是感觉比树状数组的功能强多了。只要把线段树的思想理解,然后把实现过程,递归过程了解,单点更新就没问题了。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 50001
struct node
{
    int l;
    int r;
    int v;
}tree[4*N];
void build(int l,int r,int rt)
{
    int m;
    tree[rt].l = l;
    tree[rt].r = r;
    if(l == r)
    {
        scanf("%d",&tree[rt].v);
        return;
    }
    m = (l+r)>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    tree[rt].v = tree[rt<<1].v + tree[rt<<1|1].v;
}
void update(int pos,int sc,int rt)
{
    int m;
    if(tree[rt].l == tree[rt].r)
    {
        tree[rt].v += sc;
        return ;
    }
    m = (tree[rt].l + tree[rt].r) >> 1;
    if(pos <= m)
    update(pos,sc,rt<<1);
    else
    update(pos,sc,rt<<1|1);
    tree[rt].v = tree[rt<<1].v + tree[rt<<1|1].v;
}
int query(int L,int R,int rt)
{
    int m;
    if(tree[rt].l == L&&tree[rt].r == R)
    {
        return tree[rt].v;
    }
    m = (tree[rt].l + tree[rt].r) >> 1;
    if(L > m)
    {
        return query(L,R,rt<<1|1);
    }
    else if(R <= m)
    {
        return query(L,R,rt<<1);
    }
    else
    {
        return query(L,m,rt<<1)+query(m+1,R,rt<<1|1);
    }
}
int main()
{
    int t,num = 0,x,y,n;
    char str[100];
    scanf("%d",&t);
    while(t--)
    {
        num ++;
        memset(tree,0,sizeof(tree));
        scanf("%d",&n);
        build(1,n,1);
        scanf("%s",str);
        printf("Case %d:\n",num);
        while(strcmp(str,"End") != 0)
        {
            scanf("%d%d%*c",&x,&y);
            if(strcmp(str,"Query") == 0)
            printf("%d\n",query(x,y,1));
            else if(strcmp(str,"Add") == 0)
            update(x,y,1);
            else if(strcmp(str,"Sub") == 0)
            update(x,-y,1);
            scanf("%s",str);
        }
    }
    return 0;
}

  

posted @ 2012-08-09 10:45  Naix_x  阅读(143)  评论(1编辑  收藏  举报