hiho_1070_RMQ
题目
区间最小值查询,但是支持对数组中的任意数字进行修改。
分析
采用RMQ_ST算法的O(1)算法不支持修改,因为每次修改都要重新设置动归数组。因此采用线段树解决,修改和查询的复杂度均为O(logN).
在实现的时候所犯的错误:每次更新一个数字的时候,走到线段树的某个节点,则直接 判断线段树的当前节点代表区间的最小值cur_min是否小于value, 如果大于则更新为value.这样做没有考虑到,当前所要更改的位置就是当前节点区间内最小值的位置,这样cur_min就无效了。
因此,还是需要从上到下找到线段树的叶子节点进行更新,之后递归返回的时候,利用子节点的min来更新父节点的min。
逻辑一定要严密!!!
实现
#include<iostream>
#include<string.h>
#include<iostream>
#include<queue>
#include<cmath>
#include<unordered_map>
#include<unordered_set>
#include<string>
#include<vector>
using namespace std;
const int inf = 1 << 29;
const int kMax = 10005;
struct Node{
int beg;
int end;
int min;
Node(){
min = inf;
}
};
Node gNodes[4 * kMax];
int weight[kMax];
void BuildTree(int node, int beg, int end){
gNodes[node].beg = beg;
gNodes[node].end = end;
if (beg == end){
gNodes[node].min = weight[beg];
return;
}
int left = 2 * node + 1, right = 2 * node + 2;
int mid = (beg + end) / 2;
BuildTree(left, beg, mid);
BuildTree(right, mid + 1, end);
//更新完子节点之后,再更新父节点
gNodes[node].min = gNodes[left].min < gNodes[right].min ? gNodes[left].min : gNodes[right].min;
} void Update(int node, int id, int value){
if (id < gNodes[node].beg || id > gNodes[node].end)
return; if (id == gNodes[node].beg && id == gNodes[node].end){
gNodes[node].min = value;
return;
}
int left = 2 * node + 1, right = 2 * node + 2;
int mid = (gNodes[node].beg + gNodes[node].end) / 2;
if (mid >= id){
Update(left, id, value);
}
else{
Update(right, id, value);
}
//更新完子节点之后,再更新父节点
gNodes[node].min = gNodes[left].min < gNodes[right].min ? gNodes[left].min : gNodes[right].min;
}
int Query(int node, int beg, int end){
if (gNodes[node].beg == beg && gNodes[node].end == end){
return gNodes[node].min;
}
int left = 2 * node + 1, right = 2 * node + 2;
int mid = (gNodes[node].beg + gNodes[node].end) / 2;
if (mid >= end){
return Query(left, beg, end);
}
else if (mid < beg){
return Query(right, beg, end);
}
else{
int left_min = Query(left, beg, mid);
int right_min = Query(right, mid + 1, end);
return left_min < right_min ? left_min : right_min;
}
}
int main(){
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++){
scanf("%d", &weight[i]);
}
BuildTree(0, 0, n - 1);
scanf("%d", &n);
int cmd, beg, end;
for (int i = 0; i < n; i++){
scanf("%d %d %d", &cmd, &beg, &end);
if (cmd == 0){
int result = Query(0, beg-1, end-1);
printf("%d\n", result);
}
else{
Update(0, beg-1, end);
}
}
return 0;
}
hiho_1070_RMQ的更多相关文章
随机推荐
- HashTable的实现原理
转载:http://wiki.jikexueyuan.com/project/java-collection/hashtable.html 概述 和 HashMap 一样,Hashtable 也是一个 ...
- shell脚本例子集锦(习题总结)
练习一:写一个脚本 .设定变量FILE的值为/etc/passwd .依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么 形如:(提示:LINE=`wc -l /etc/passw ...
- 配置Python+selenium+firefox自动化测试
1.安装python.默认安装 2.安装pip.下载pip-1.5.4包,解压pip-1.5.4,放在C盘,进入pip目录-->键入命令:python setup.py install 再进入 ...
- Duilib将UI资源文件打包到exe教程
转载:http://www.voidcn.com/blog/w839687571/article/p-6001921.html 转载:http://www.voidcn.com/blog/x35698 ...
- Linux源代码分析工具链
前言 看源代码是一个程序员必须经历的事情,也是可以提升能力的一个捷径.个人认为: 要完全掌握一个软件的方法只有阅读源码. 在Windows下有sourceinsight这个源码阅读软件(虽然我没用过, ...
- GHOST系统锁定主页常用软件及解决方案
网络下载的GHOST系统,很多锁定主页,无法用360等更改,卸载里面也不含有锁定主页的软件名称.其中常用的锁定的主页的软件有: 1.百度组件. 一般在C盘含有BAIDU的文件夹内,找到卸载即可. 2. ...
- javascript/jquery判断是否为undefined或是null!
var exp = undefined; if (typeof(exp) == "undefined"){ alert("undefined");} 注意 ...
- MySql使用show processlist查看正在执行的Sql语句
今天上班例行的查看了下服务器的运行状况,发现服务器特卡,是mysqld这个进程占用CPU到了99%导致的. 比较好奇是那个程序在使用mysql导致cpu这么高的,通过show processlist命 ...
- MSChart使用
制作报表的时候结果出现画红线处的信息太散, 如果没必要全部显示出来,我们可以使用这种效果: 注意和前面的区分,这个功能叫做Collect Pie Slices(收集分区) 要实现此功能,应先了解相关信 ...
- servlet&jsp高级:第五部分
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...