果枫-国峰

hdu 1166

题意:中文题,省。

 

解法:线段树。

 

注意:输入,输出最后用scanf(),printf(),其他的可能超时。

 

ac代码:

View Code
//线段树,节点更新,区间求和
#include<iostream>
#include<string>
using namespace std;


const int M=50000+10;//最大区间
int num[M];//记录每一个营的人数

struct treestruct
{
    int left;//左区间
    int right;//右区间
    int sum;//区间求和
}node[M*3];//节点数大约是最大区间的3倍

int build(int low,int top,int index)//建树:父节点是左右节点之和
{
    node[index].left=low;
    node[index].right=top;
    if(low==top)    //是否递归到最低
    {
        return     node[index].sum=num[low];
    }
    int mid=(low+top)>>1;
    return node[index].sum=build(low,mid,index*2)+build(mid+1,top,index*2+1);//父节点是左右节点之和
}

void updata(int k,int s,int index)//在节点k上加上s,所以k的每一个父节点都要加s
{
    node[index].sum+=s;
    if(node[index].left==node[index].right&&node[index].left==k)
    {
        return ;
    }
    int mid=(node[index].left+node[index].right)>>1;
    if(mid>=k)   //k在左子树中
        updata(k,s,index*2);
    else     //k在右子树中
        updata(k,s,index*2+1);
}

int search(int l,int r,int index)
{
    if(node[index].left==l&&node[index].right==r)//找到完全重合的区间,直接返回node[].sum值
        return node[index].sum;

    int mid=(node[index].left+node[index].right)>>1;

    if(mid>=r)      //搜索区间位于左子树
        return search(l,r,index*2);
    else
        if(mid<l)     //搜索区间位于右子树
            return search(l,r,index*2+1);
        else       //搜索区间位于左右子树,即将区间分为2部分
        {
            return search(l,mid,index*2)+search(mid+1,r,index*2+1);
        }

}

int main()
{
    int t;
    scanf("%d",&t);
    int k=1;
    while(t--)
    {
        int i,j;

        int n;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
        }

        build(1,n,1);

        printf("Case %d:\n",k++);

        char ch[10];
        int a,b;    
        while(scanf("%s",ch))
        {
            if(ch[0]=='A')
            {
                scanf("%d%d",&a,&b);
                updata(a,b,1);
            }
            if(ch[0]=='S')
            {
                scanf("%d%d",&a,&b);
                updata(a,-b,1);
            }
            if(ch[0]=='Q')
            {
                scanf("%d%d",&a,&b);
                printf("%d\n",search(a,b,1));
            }
            if(ch[0]=='E')
                break;
        }
    }
    return 0;
}
/*
10
1 2 3 4 5 6 7 8 9 10
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End 

*/

 

posted on 2012-09-10 17:01  果枫-国峰  阅读(113)  评论(0编辑  收藏  举报

导航