【转】HDU-1166 敌兵布阵 : 熟练"建树->插数->查询“过程

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
#define Size 50000

struct node
{
        int L, R, V;
        node* lchild;
        node* rchild;
}Tree[2*Size];// 线段树 用到指针 所以整个线段树 所占空间为 2倍叶子节点-1

int Mid( node* root )
{
        return (root->L + root->R)/2;
}

int nCount;

void BuildTree( node* root, int L, int R )// 初始化区间为[L,R]的线段树
{
        root -> L = L;
        root -> R = R;
        root -> V = 0;
        if( L == R )
            return ;
        nCount++;
        root -> lchild = Tree + nCount;
        nCount++;
        root -> rchild = Tree + nCount;

        BuildTree( root->lchild, L, (L+R)/2 );
        BuildTree( root->rchild, (L+R)/2+1, R );
}

void Insert( node* root, int i, int v ) 在单位区间 i 上 插入 值为v的数
{
        if( root->L == i && root->R == i )
        {
                root->V = v;
                return ;
        }
        root -> V += v;// 更新 所在路径上区间的值
        if( i <= Mid( root ) )
            Insert( root->lchild, i, v );
        else
            Insert( root->rchild, i, v );
}

void Add( node* root, int i, int j )// 在 i上 加上 j
{
        if( root->L == i && root->R == i )
        {
                root->V += j;
                return ;
        }
        root->V += j;
        if( i<=Mid( root ) )
            Add( root->lchild, i, j );
        else
            Add( root->rchild, i, j );
}

int Query( node* root, int s, int e )//  区间 [s,e] 求和
{
            if( root->L==s && root->R == e )
                return root->V;

            if( e<=Mid(root) )
                return Query( root->lchild, s, e );
            else if( s>=Mid(root)+1 )
                return Query( root->rchild, s, e );
            else
                return Query( root->lchild, s, Mid(root) )
                            +Query( root->rchild, Mid(root)+1, e );
}

int main()
{
        int  T, N;
        cin>>T;
        for( int i=1; i<=T; i++ )
        {
                        printf( "Case %d:\n", i );

                        nCount = 0;
                        scanf( "%d", &N );
                        BuildTree( Tree, 1, N );

                        int Val;
                        for( int j=1; j<=N; j++ )
                        {
                                scanf("%d", &Val);
                                Insert( Tree, j, Val );
                        }

                        string cmd;
                        int a, b;

                        while(cin>>cmd && cmd!="End"){
                                if( cmd == "Query" )
                                {
                                        scanf( "%d %d", &a, &b );
                                        cout<<Query( Tree, a, b )<<endl;
                                }
                                else if( cmd == "Add" )
                                {
                                        scanf( "%d %d", &a, &b );
                                        Add( Tree, a, b );
                                }
                                else if( cmd == "Sub" )
                                {
                                        scanf( "%d %d", &a, &b );
                                        Add( Tree, a, -b );
                                }
                        }
        }
        return 0;
}

 

posted @ 2015-07-23 21:56  _SunDaSheng  阅读(133)  评论(0编辑  收藏  举报