题目

区间最小值查询,但是支持对数组中的任意数字进行修改。

分析

采用RMQ_ST算法的O(1)算法不支持修改,因为每次修改都要重新设置动归数组。因此采用线段树解决,修改和查询的复杂度均为O(logN). 
    在实现的时候所犯的错误:每次更新一个数字的时候,走到线段树的某个节点,则直接 判断线段树的当前节点代表区间的最小值cur_min是否小于value, 如果大于则更新为value.这样做没有考虑到,当前所要更改的位置就是当前节点区间内最小值的位置,这样cur_min就无效了。 
    因此,还是需要从上到下找到线段树的叶子节点进行更新,之后递归返回的时候,利用子节点的min来更新父节点的min。 
    逻辑一定要严密!!!

实现

  1. #include<iostream>
  2. #include<string.h>
  3. #include<iostream>
  4. #include<queue>
  5. #include<cmath>
  6. #include<unordered_map>
  7. #include<unordered_set>
  8. #include<string>
  9. #include<vector>
  10. using namespace std;
  11. const int inf = 1 << 29;
  12. const int kMax = 10005;
  13. struct Node{
  14. int beg;
  15. int end;
  16. int min;
  17. Node(){
  18. min = inf;
  19. }
  20. };
  21. Node gNodes[4 * kMax];
  22. int weight[kMax];
  23. void BuildTree(int node, int beg, int end){
  24. gNodes[node].beg = beg;
  25. gNodes[node].end = end;
  26. if (beg == end){
  27. gNodes[node].min = weight[beg];
  28. return;
  29. }
  30. int left = 2 * node + 1, right = 2 * node + 2;
  31. int mid = (beg + end) / 2;
  32. BuildTree(left, beg, mid);
  33. BuildTree(right, mid + 1, end);
  34. //更新完子节点之后,再更新父节点
  35. gNodes[node].min = gNodes[left].min < gNodes[right].min ? gNodes[left].min : gNodes[right].min;
  36. }
  37.  
  38. void Update(int node, int id, int value){
  39. if (id < gNodes[node].beg || id > gNodes[node].end)
  40. return;
  41.  
  42. if (id == gNodes[node].beg && id == gNodes[node].end){
  43. gNodes[node].min = value;
  44. return;
  45. }
  46. int left = 2 * node + 1, right = 2 * node + 2;
  47. int mid = (gNodes[node].beg + gNodes[node].end) / 2;
  48. if (mid >= id){
  49. Update(left, id, value);
  50. }
  51. else{
  52. Update(right, id, value);
  53. }
  54. //更新完子节点之后,再更新父节点
  55. gNodes[node].min = gNodes[left].min < gNodes[right].min ? gNodes[left].min : gNodes[right].min;
  56. }
  57. int Query(int node, int beg, int end){
  58. if (gNodes[node].beg == beg && gNodes[node].end == end){
  59. return gNodes[node].min;
  60. }
  61. int left = 2 * node + 1, right = 2 * node + 2;
  62. int mid = (gNodes[node].beg + gNodes[node].end) / 2;
  63. if (mid >= end){
  64. return Query(left, beg, end);
  65. }
  66. else if (mid < beg){
  67. return Query(right, beg, end);
  68. }
  69. else{
  70. int left_min = Query(left, beg, mid);
  71. int right_min = Query(right, mid + 1, end);
  72. return left_min < right_min ? left_min : right_min;
  73. }
  74. }
  75. int main(){
  76. int n;
  77. scanf("%d", &n);
  78. for (int i = 0; i < n; i++){
  79. scanf("%d", &weight[i]);
  80. }
  81. BuildTree(0, 0, n - 1);
  82. scanf("%d", &n);
  83. int cmd, beg, end;
  84. for (int i = 0; i < n; i++){
  85. scanf("%d %d %d", &cmd, &beg, &end);
  86. if (cmd == 0){
  87. int result = Query(0, beg-1, end-1);
  88. printf("%d\n", result);
  89. }
  90. else{
  91. Update(0, beg-1, end);
  92. }
  93. }
  94. return 0;
  95. }

hiho_1070_RMQ的更多相关文章

随机推荐

  1. 【20160924】GOCVHelper 图像增强部分(4)

    //使得rect区域半透明     Mat translucence(Mat src,Rect rect,int idepth){         Mat dst = src.clone();     ...

  2. 【20160924】GOCVHelper综述

    GOCVHelper(GreenOpen Computer Version Helper )是我在这几年编写图像处理程序的过程中积累下来的函数库.主要是对Opencv的适当扩展和在实现Mfc程序时候的 ...

  3. JAVA基础知识之JVM-——类初始化

    我们通常说的类初始化,其实要分为三个阶段,类加载,连接,和初始化.他们大致完成以下功能.类加载将class文件载入内存,类连接进行内存分配,初始化进行变量赋值. 类的加载,连接和初始化 java.la ...

  4. 基于@AspectJ和schema的aop(二)---@AspectJ基础语法

    @AspectJ使用jdk5.0和正规的AspectJ切点表达式描述切面, 由于spring只支持方法的连接点,所以Spring只支持部分AspectJ的切点语言. 1.切点表达式函数 AspectJ ...

  5. POJ 3061 Subsequence 尺取法

    转自博客:http://blog.chinaunix.net/uid-24922718-id-4848418.html 尺取法就是两个指针表示区间[l,r]的开始与结束 然后根据题目来将端点移动,是一 ...

  6. svn转移版本库

    1.导出 svnadmin dump命令语法svnadmin dump REPOS_PATH [-r LOWER[:UPPER]] [--incremental] 示例:svnadmin dump E ...

  7. [SAP ABAP开发技术总结]客户端文本文件、Excel文件上传下载

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  8. CUBRID学习笔记 8 复制数据库

    1  export  database  类似sqlserver的分离数据库 cubrid unloaddb demodb分离后生成三个文件 demodb_objects, demodb_indexe ...

  9. Berkeley 四种产品如何选择?

    Berkeley 四种产品如何选择? 四种产品综览 Berkeley 可供选择的四款产品: DS: 简单的.支持单写单读的数据存储:支持高并发,多进程同时读操作:不支持锁,这就意味着当程序在进行更新和 ...

  10. Sbt的使用初步和用sbt插件生成eclipse工程

    以前一直是用maven去管理java项目,现在开始写scala项目了但是在scala-ide中去编译scala项目和sbt的区别一直没弄清楚受到文章:http://my.oschina.net/yjw ...