zoukankan      html  css  js  c++  java
  • 线段树

      题意:假设整个货架上从左到右摆放了N种商品,并且依次标号为1到N,每次给出一段区间[L, R],要做的是选出标号在这个区间内的所有商品重量最轻的一种,并且告诉这个商品的重量。但是在这个过程中,可能会因为其他人的各种行为,对某些位置上的商品的重量产生改变(如更换了其他种类的商品)。

      线段树求区间元素的性质的题目。线段树使用数组来实现完全二叉树的结构,下标从1开始,一个结点i的左孩子为2*i,右孩子为2*i+1。假设父结点的区间范围为[l,r],则左孩子的区间范围为:[l,mid];右孩子的区间范围为:[mid+1,r]。下面给出实现代码。

    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    #define M 100000005 
    struct Node{
        int l, r, min;
    };
    
    Node nodes[M];
    int arr[M];
    
    int min(int a, int b){
        return a < b ? a : b;
    }
    
    void buildTree(int l, int r, int i){
        nodes[i].l = l;
        nodes[i].r = r;
        if (l == r){
            nodes[i].min = arr[l];
            return;
        }
        int mid = (l + r) >> 1;
        buildTree(l, mid, 2 * i);
        buildTree(mid + 1, r, 2 * i + 1);
        nodes[i].min = min(nodes[2 * i].min, nodes[2 * i + 1].min);
    }
    
    void update(int id, int price, int i){
        if (nodes[i].l == nodes[i].r){
            nodes[i].min = price;
            return;
        }
        int mid = (nodes[i].l + nodes[i].r) >> 1;
        if (id <= mid){
            update(id, price, i * 2);
        }
        else{
            update(id, price, i * 2 + 1);
        }
        nodes[i].min = min(nodes[i * 2].min, nodes[i * 2 + 1].min); //!!!
    }
    
    
    int query(int l, int r, int i){
        if (l == nodes[i].l && r == nodes[i].r)
            return nodes[i].min;
        int mid = (nodes[i].l + nodes[i].r) >> 1;
        if (r <= mid){ // 在左子树中
            return query(l, r, 2 * i);
        }
        else if (l > mid){
            return query(l, r, 2 * i + 1);
        }
        else{
            return min(query(l, mid, 2 * i), query(mid + 1, r, 2 * i + 1));
        }
    }
    
    int main(){
        int m, n, f, l, r, id, price;
        while (scanf("%d", &n) != EOF){
            for (int i = 1; i <= n; ++i){
                scanf("%d", &arr[i]);
            }
            buildTree(1, n, 1);
            scanf("%d", &m);
            while (m--){
                scanf("%d", &f);
                if (f == 1){
                    scanf("%d%d", &id, &price);
                    update(id, price, 1);
                }
                else{
                    scanf("%d%d", &l, &r);
                    printf("%d
    ", query(l, r, 1));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    HDFS datanode源码分析
    hive udaf开发入门和运行过程详解
    hive原生和复合类型的数据加载和使用
    tomcat部署web应用(转)
    HDFS namenode源码分析
    HDFS dfsclient写文件过程 源码分析
    hive中UDTF编写和使用(转)
    HDFS dfsclient读文件过程 源码分析
    MapReduce源码分析总结(转)
    DataRabbit 轻量的数据访问框架(09) -- IDataSchemaAccesser
  • 原文地址:https://www.cnblogs.com/yplhh/p/4740333.html
Copyright © 2011-2022 走看看