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;
}
时间: 2024-10-12 10:02:28

HDU-1166 敌兵布阵 : 熟练"建树->插数->查询“过程的相关文章

HDU 1166 敌兵布阵 (线段树 &amp; 树状数组)

敌兵布阵 Time Limit:1000MS    Memory Limit:32768KB    64bit IO Format:%I64d & %I64u SubmitStatus 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的

HDU 1166 敌兵布阵 (线段树 单点更新)

题目链接 线段树掌握的很差,打算从头从最简单的开始刷一波, 嗯..就从这个题开始吧! 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <cstdlib> 6 #include <algorithm> 7 const int maxn = 50000+10; 8 using namespace std

[HDU 1166 敌兵布阵] 线段树 或 树状数组

1 #include<iostream> 2 #include<cstdio> 3 #include<memory.h> 4 using namespace std; 5 int n,C[50005]; 6 //-------------------------- 7 int lowbit(int x){ 8 return x&-x; 9 } 10 int sum(int x){ 11 int ret=0; 12 while(x>0){ 13 ret+=C

【线段树I:母题】hdu 1166 敌兵布阵

[线段树I:母题]hdu 1166 敌兵布阵 题目链接:hdu 1166 敌兵布阵 题目大意 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又開始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况. 因为採取了某种先进的监測手段,所以每一个工兵营地的人数C国都掌握的一清二楚,每一个工兵营地的人数都有可能发生变动.可能添加或降低若干人手,但这些都逃只是C国的监视. 中央情报局要研究敌人到底演习什么战术,所以

【线段树一】HDU 1166 敌兵布阵

敌兵布阵Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 37406    Accepted Submission(s): 15774 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是

【线段树】hdu 1166 敌兵布阵

[线段树]hdu 1166 敌兵布阵 题目链接:hdu 1166 敌兵布阵 题目大意 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视. 中央情报局要研究敌人究竟演习什么战术,所以Tidy要随时

hdu 1166:敌兵布阵(树状数组,练习题)

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 37773    Accepted Submission(s): 15923 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就

hdu 1166 敌兵布阵 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 题目意思:给出 N 个数你,通过对某些数进行更改(或者 + 或者 -),当输入的是 Query 的时候,需要计算出 某个区间的和. 树状数组第一题,算是模板吧 ^_^ 有个小细节,wa 了几次,细心~细心~~~细心 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <

hdu 1166 敌兵布阵 线段树 点更新

// hdu 1166 敌兵布阵 线段树 点更新 // // 这道题裸的线段树的点更新,直接写就可以了 // // 一直以来想要进线段树的坑,结果一直没有跳进去,今天算是跳进去吧, // 虽然十分简单,十分的水,继续加油 #include <algorithm> #include <bitset> #include <cassert> #include <cctype> #include <cfloat> #include <climits