zoukankan      html  css  js  c++  java
  • 范围最小值(RMQ)问题 Anti

    问题:

      给出一个n个元素的数组,a[1], a[2], …… , a[n],设计一个数据结构,支持查询操作RMQ(L, R),计算min{a[L], a[L+1], …… , a[R]}。

    分析:

      循环计算会超时,用Tarjan的Sparse-Table算法,预处理时间是O(nlogn),查询只需要O(1)。

      令d[i][j]表示从i开始,长度为2的j次方的一段元素的最小值。

      则d[i][j] = min(d[i][j-1], d[i+(1<<(j-1)][j-1])。

    代码:

      

    #include <cstdio>
    #include <algorithm>
    //#include <cmath>
    using namespace std;
    const int MAX = 100;
    int n, a[MAX+10];
    int d[MAX+10][MAX+10];//二维应该是floor(log(1.0*MAX)/log(2.0)),但是不知为什么编译有问题。。
    int RMQ(int l, int r)
    {
        int k = 0;
        while((1<<(k+1)) <= r-l+1)k++;
        //也可以k = log(1.0 * r-l+1)/log(2.0);
        return min(d[l][k], d[r-(1<<k)+1][k]);
    }
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        for(int i = 1; i <= n; i++)
            d[i][0] = a[i];
        for(int j = 1; (1<<j) <= n; j++)
            for(int i = 1; i+(1<<j)-1 <= n; i++)
                d[i][j] = min(d[i][j-1], d[i+(1<<(j-1))][j-1]);
        int l, r;
        while(scanf("%d %d", &l, &r) != EOF)
            printf("%d\n", RMQ(l, r));
        return 0;
    }
  • 相关阅读:
    函数中,易遗忘记载
    常用函数源码
    装饰器之自我理解
    函数名、闭包及迭代器
    函数2
    trap(陷井)
    文件操作
    搭建Pxe引导RamOS Linux内存系统
    X86服务器BMC基板管理控制器介绍
    Linux操作系统自动部署--镜像格式qcow2
  • 原文地址:https://www.cnblogs.com/wolfred7464/p/3107039.html
Copyright © 2011-2022 走看看