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;

}

  

你可能感兴趣的:(HDU)