• 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
    ", result);
    		}
    		else{
    			Update(0, beg-1, end);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    python 全栈基础作业题
    计算机基础之二:操作系统的发展史
    计算机基础系列之一:计算机硬件概述
    饼图
    折线图
    win_diy_monkey demo
    csv,Excel
    uiautomator2
    win ui自动化测试
    html
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/5541089.html
Copyright © 2020-2023  润新知