HDU1166 敌兵布阵 线段树详解
题解:
更新是线段树的单点更新,简单一点。
有50000个阵营,40000查询,用普通数组肯定超时。区间求和和区间查询问题用线段树最好不过了。
先说说什么是线段树。
区间[1,10]用树的方法存起来,怎么存呢,来看下图:

线段树结构主要用于区间查询和更新。时间复杂度为lgN。虽然空间大了但时间快了。对于数据到达 亿 级别的,效果尤为显著。
知道了线段树的结构,那么怎么用代码实现建树,查询以及更新呢..看代码。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring> //杭电上 如果用c++编译器则改成incluce<string> ,c++编译器不支持cstring不知道为啥。 using namespace std; //这道题建议用G++编译器提交 const int MAX=50001; typedef struct node //定义树节点
{
node(){l=0,r=0,data=0;} //构造函数
int l,r; //区间[l,r]
int data; //数据,这里指区间[l,r]的和
}TreeNode; TreeNode treeNode[MAX<<4];
int a[MAX]; void update(int p) //向上更新
{
treeNode[p].data=treeNode[p*2].data+treeNode[p*2+1].data;
} void buildTree(int p,int l,int r) //建树,p是节点编号,从1开始,l,r是区间
{
treeNode[p].l=l;
treeNode[p].r=r; if(l==r) //如果是叶子节点,则赋值 返回
{
treeNode[p].data=a[l];
return;
}
int mid=(l+r)>>1; //
buildTree(p<<1,l,mid); //递归地创建左子树和右子树 p<<1 <==> p*2
buildTree(p<<1|1,mid+1,r); // p<<1|1 <==> p*2+1
update(p); //回溯的时候更新data值
return;
} void add(int p,int k,int x) //添加方法,p节点编号(索引),k为要修改的区间[k,k],x为要修改的值
{
if(treeNode[p].l==k&&treeNode[p].r==k) //如果找到区间[k,k]
{
treeNode[p].data+=x;
return;
}
int mid=(treeNode[p].l+treeNode[p].r)/2;
if(k<=mid) add(p<<1,k,x); //如果要修改的点在当前区间的左边,查找左子树
else add(p<<1|1,k,x); //如果要修改的点在当前区间的右边,在右子树里查找
update(p); //回溯的时候更新data信息
return;
} int query(int p,int l,int r) //p为节点编号,查询区间[l,r];
{
if(treeNode[p].l>=l&&treeNode[p].r<=r) //如果当前节点的区间在[l,r]内
{
return treeNode[p].data;
}
if(treeNode[p].l>r||treeNode[p].r<l) //如果当前区间和要查找的区间没有交集
{
return 0;
}
int sum=0;
sum+=query(p<<1,l,r); //查询左子树
sum+=query(p<<1|1,l,r); //查询右子树
return sum;
} int main()
{
int n,tt; //区间[1,n],有tt组测试数据
//cin>>tt; //测试数据 输入就有 40000+,用cin就超时,scanf秒过,或者能用scanf的就用scanf
scanf("%d",&tt);
for(int t=1;t<=tt;t++)
{
//cin>>n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
//cin>>a[i];
scanf("%d",&a[i]);
}
buildTree(1,1,n); //建树,节点编号从1开始,区间[1,n] string op; //操作 printf("Case %d:\n",t); while(cin>>op) //string 类型只能用cin输入
{
if(op=="Query")
{
int a,b;
//cin>>a>>b;
scanf("%d%d",&a,&b);
//cout<<query(1,a,b)<<endl;
printf("%d\n",query(1,a,b));
continue;
}
if(op=="Add")
{
int a,b;
//cin>>a>>b;
scanf("%d%d",&a,&b);
add(1,a,b);
continue;
}
if(op=="Sub")
{
int a,b;
//cin>>a>>b;
scanf("%d%d",&a,&b);
add(1,a,-b);
continue;
}
if(op=="End")
{
break;
}
} }
return 0;
}
HDU1166 敌兵布阵 线段树详解的更多相关文章
- hdu 1166 敌兵布阵(线段树详解)
Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任 ...
- HDU-1166敌兵布阵(线段树)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submissi ...
- hdu1166 敌兵布阵(线段树 求区间和 更新点)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- hdu1166 敌兵布阵 线段树(区间更新)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- HDU1166 敌兵布阵(线段树)
C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...
- 【生活没有希望】hdu1166敌兵布阵 线段树
线段树水题刷刷,生活没有希望 最近看到代码跟树状数组差不多短的非递归线段树,常数也很小——zkw线段树 于是拿道水题练练手 短到让人身无可恋 ;pos;pos/=) a[pos]+=x;} ,ans= ...
- HDU1166 敌兵布阵 —— 线段树单点修改
题目链接:https://vjudge.net/problem/HDU-1166 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布 ...
- HDU1166 敌兵布阵 [线段树模板]
题意:在序列中修改单点和查询区间和 #include<iostream> #include<cstdio> #include<cstring> #define ls ...
- HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)
HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...
随机推荐
- IIS访问php页面问题,报告404错误
IIS访问php页面出现问题,所有php页面找不到,显示404页面,html页面可以正常访问. 搜索结果: 方案1: 打开WEB服务扩展,把“所有未知ISAPI扩展”设为允许! 方案2: PHP没有完 ...
- SQL数据查询
CREATE TABLE class0328( id INT, cname ), sex ), age INT, birthday DATE, html DOUBLE, js DOUBLE, scor ...
- bzoj 1189: [HNOI2007]紧急疏散evacuate 分层图最大流_拆点_二分
Description 发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域.每个格子如果是'.',那么表示这是一 块空地:如果是'X',那么表示这是一面墙,如果是'D',那么表示这是 ...
- ojdbc14:11.2.0.1.0出错
首先在相关目录下找到你的ojdbc14的包:比如 我的出错问题:(之前是11.2.0.1.0,后改为10.2.0.1.0) 我的包路径:C:\my_java\maven_repository\com\ ...
- C语言基础 (7) 输入输出
复习 // 定义数组时 []内部尽量用常量 // 定义数组时,数组名在同一{}内部是唯一的,不能和变量.其他数组名同名 // 使用数组时 []可以是常量,变量,表达式 // 定义一个数组,数组名字叫a ...
- JavaScript 三要素
一个完整的JavaScript 实现由3部分组成: ECMACcript ECMAScript 规定了这门语言的下列组成部分: 语法 类型 语句 关键字.保留字 操作符 对象为什么要使用DOM? ...
- (3)Spring Boot热部署【从零开始学Spring Boot】
在编写代码的时候,你会发现我们只是简单把打印信息改变了下,就需要重新部署,如果是这样的编码方式,那么我们估计一天下来之后就真的是打几个Hello World之后就下班了.那么如何解决热部署的问题呢?那 ...
- PHP 防xss攻击
PHP直接输出html的,可以采用以下的方法进行过滤: 1.htmlspecialchars函数 2.htmlentities函数 3.HTMLPurifier.auto.php插件 4.Remove ...
- C#中的全局程序集缓存定义
安装有公共语言运行时的每台计算机都具有称为全局程序集缓存的计算机范围内的代码缓存.全局程序集缓存中存储了专门指定给由计算机中若干应用程序共享的程序集. 应当仅在需要时才将程序集安装到全局程序集缓存中以 ...
- 在IntelliJ IDEA中创建Maven多模块项目
在IntelliJ IDEA中创建Maven多模块项目 1,创建多模块项目选择File>New>Project 出现New Project窗口左侧导航选择Maven,勾选右侧的Create ...