前言:

线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。       对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b]。因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度。       使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。而未优化的空间复杂度为2N,因此有时需要离散化让空间压缩。

----来自百度百科;
 
 
正文:

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1166

这个题直接用暴力的话,超时。

可以用,线段树,快很多,

这是我做的第一个线段树的题。

线段树可以分为几个部分

第一  建树

第二 插入数据

第三 查找数据

我的AC代码

#include<stdio.h> #include<string.h>

#define MAXSIZE 50005

struct node

{

int left,right,sum;

} tree[MAXSIZE*4];

void build(int node,int left,int right)//建树,二分的思路

{

tree[node].left=left;

tree[node].right=right;

tree[node].sum=0;

if(left==right)       //如果左边界与右边界相等,则说明不能再二分了即就是,像一棵二叉树一样到了最低了;

return ;

int mid=(left+right)/2;

build(node*2,left,mid);

build(node*2+1,mid+1,right);

}

void update(int node,int pos,int val)//插入数据,更新数据

{

tree[node].sum+=val;

if(tree[node].left==pos&&tree[node].right==pos)

return ;

int mid=(tree[node].left+tree[node].right)/2;

if(pos<=mid)

update(node*2,pos,val);

else

update(node*2+1,pos,val); }

int query(int node,int left,int right) //查找数据,

{

if(tree[node].left==left&&tree[node].right==right)

return tree[node].sum;

int mid=(tree[node].left+tree[node].right)/2;

if(right<=mid)

return query(node*2,left,right);

else if(left>mid)

return query(node*2+1,left,right);

else

return query(node*2,left,mid)+query(node*2+1,mid+1,right);

}

int main(void)

{

int t,n,k,i;

int x,y,c;

char s[20];

scanf("%d",&t);

k=0;

while(t--)

{

scanf("%d",&n);

build(1,1,n);

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

for(i=1; i<=n; i++)

{

scanf("%d",&c);

update(1,i,c);

}

while(scanf("%s",s)==1&&s[0]!='E')

{

scanf("%d%d",&x,&y);

if(s[0]=='Q')

{

printf("%d\n",query(1,x,y));

}

else if(s[0]=='A')

{

update(1,x,y);

}

else if(s[0]=='S')

{

update(1,x,-y);

}

}

}

return  0;

}

网上代码

#include <stdio.h> #include <string.h> #define MAXSIZE 50001

struct node {     int left, right ;     int sum ; }tree[MAXSIZE * 4];

int     tcase, n ;

void build (int node, int left, int right) {     tree[node].left     = left ;     tree[node].right    = right ;     tree[node].sum      = 0 ;     if (left == right)         return ;     int mid = (left + right) / 2 ;     build (node * 2, left, mid) ;     build (node * 2 + 1, mid + 1, right) ; }

void update (int node, int pos, int val) {     // 当前区间的总人数增加     tree[node].sum += val ;     // 刚好走到第pos 个营地所在的叶子     if (tree[node].left == pos &&tree[node].right == pos)     {         return ;     }     int mid = (tree[node].left + tree[node].right) / 2 ;     // 若营地在当前区间的左半边     if (pos <= mid)         update (node * 2, pos, val) ;     // 若营地在当前区间的右半边     else         update (node * 2 + 1, pos, val) ; }

int query (int node, int left, int right) {     // 若区间刚好匹配     if (tree[node].left == left &&tree[node].right == right)         return tree[node].sum ;

// 若区间无交集     //if (tree[node].left > right ||tree[node].right < left)         //return 0 ;

// 若区间有交集     int mid = (tree[node].left + tree[node].right) / 2 ;

// 若查询区间在左半边     if (right <= mid)         return query (node * 2, left, right) ;     // 若查查询区间在右半边     else if (mid < left)         return query (node * 2 + 1, left, right) ;     // 若查询区间横跨当前区间的中点     else         return query (node * 2, left, mid) + query (node * 2 + 1, mid + 1, right) ; }

int main () {     char    str[20] ;     int     i, j ;     int     x, y ;

while (scanf ("%d", &tcase) != EOF)     {         for (j = 1 ; j <= tcase ; ++j)         {             scanf ("%d", &n) ;             build (1, 1, n) ;             for (i = 1 ; i <= n ; ++i)             {                 scanf ("%d", &x) ;                 // 从根部开始查找,第i 个营地的值增加x                 update (1, i, x) ;             }             printf ("Case %d:\n", j) ;             while (scanf ("%s", str), *str != 'E')             {                 scanf ("%d%d", &x, &y) ;                 if (*str == 'Q')                     printf ("%d\n", query (1, x, y)) ;                 else if (*str == 'A')                     update (1, x, y) ;                 else if (*str == 'S')                     update (1, x, -y) ;             }         }     }     return 0 ; }

HDU-1166-敌兵布阵(线段树)的更多相关文章

  1. HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)

    HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...

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

    // hdu 1166 敌兵布阵 线段树 点更新 // // 这道题裸的线段树的点更新,直接写就能够了 // // 一直以来想要进线段树的坑,结果一直没有跳进去,今天算是跳进去吧, // 尽管十分简单 ...

  3. HDU 1166 敌兵布阵(线段树单点更新,板子题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

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

    敌兵布阵 单点更新和区间更新还是有一些区别的,应该注意! [题目链接]敌兵布阵 [题目类型]线段树单点更新 &题意: 第一行一个整数T,表示有T组数据. 每组数据第一行一个正整数N(N< ...

  5. HDU 1754 线段树 单点跟新 HDU 1166 敌兵布阵 线段树 区间求和

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. HDU 1166 敌兵布阵 <线段树 单点修改 区间查询>

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  7. hdu 1166 敌兵布阵 (线段树、单点更新)

    敌兵布阵Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  8. hdu 1166 敌兵布阵 线段树区间修改、查询、单点修改 板子题

    题目链接:敌兵布阵 题目: C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视 ...

  9. HDU 1166 敌兵布阵 线段树

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  10. HDU 1166 - 敌兵布阵 - [线段树][树状数组]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

随机推荐

  1. word2016怎么从第三页开始设置页码

    在Word中,默认为一节,每节的页码是连续的,若想在一个Word文档中,前2页不设页码,从第3页开始设置页码,必须插入分节符,使文档分成两节,这样就可以单独设置页码.操作步骤:1.将光标放在第4页的首 ...

  2. win7 安装 vagrant + centos + virtualbox

    Vagrant 是一款用来构建虚拟开发环境的工具,非常适合 php/python/ruby/java 这类语言开发 web 应用,“代码在我机子上运行没有问题”这种说辞将成为历史. 我的是在win7系 ...

  3. ecos的mvcl

    m 数据模型抽象层 v 视图 c 控制器 l 业务逻辑 mvc与mvcl区别 mvc中的m是mvcl中m+l

  4. 我的git常用命令

    git add . # 将所有修改过的工作文件提交暂存区 git commit -m ""

  5. 17.4.3 使用MulticastSocket实现多点广播(5)

    该类主要实现底层的网络通信功能,在该类中提供了一个broadCast()方法,该方法使用Multicast Socket将指定字符串广播到所有客户端:还提供了sendSingle()方法,该方法使用D ...

  6. PHP和MySQL Web开发(原书第4版) 高清PDF+源代码

    PHP和MySQL Web开发(原书第4版) 高清PDF+源代码 [日期:2014-08-06] 来源:Linux社区  作者:Linux [字体:大 中 小]     内容简介 <PHP和My ...

  7. 一、Hadoop基本操作命令

    查看hadoop版本 hadoop version 启动与关闭 启动Hadoop 1.         进入HADOOP_HOME目录. 2.         执行sh bin/start-all.s ...

  8. Extjs4中的常用组件:Grid、Tree和Form

    至此我们已经学习了Data包和布局等API.下面我们来学习作为Extjs框架中我们用得最多的用来展现数据的Grid.Tree和Form吧! 目录: 5.1. Grid panel 5.1.1. Col ...

  9. STM32驱动W25X64存储器

    W25X64 是华邦公司推出的大容量 SPI  FLASH 产品,W25X64 的容量为 64Mbit(8M),该系列还有 W25Q80/16/32 等.W25X16,W25X32,W25X64分别有 ...

  10. IOS开发-UI学习-UITextField的各种属性设置

    UITextField是IOS中非常常用的一个控件,用来接收用户输入信息,完成应用和用户的交互.它的主要属性设置如下: //初始化textfield并设置位置及大小 UITextField *text ...