• RMQ(st表写法)


    最近很累 南昌打铁 选拔赛打的一塌糊涂 没有心态了 颓了好久 今天写写st表

    首先 RMQ(Range MIinimum/Maximum Query 离线查询区间最大最小值)

    有很多种写法比如线段树(蔡) 树状数组(不会) st表

    那么来讲讲st表

    首先st表的主体其实就是一个预处理的数组

    预处理时间复杂度o(nlogn)  查询时间复杂度o(1) 空间复杂度o(n)

    首先我们来看预处理代码 然后根据代码讲解st表的

     for (int i = 1; i <= n; i++)
            cin >> f[i][0];
        for (int j = 1; j <= 20; j++)
            for (int i = 1; i <= n; i++)
                if (i + (1 << j) - 1 <= n)
                    f[i][j] = min(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);

    如果一个区间i的长度为1,那么f[i][0]就为位置i对应的值 对于一个长度为2的区间a—>b,

    我们可以用f[a][1]来表示这个区间的极值,那么对于这个区间而言,

    f[a][1]的最小值就可以看做min(a,b),即可以看做min(f[a][0],f[a+(1<<0)][0])。

    如果我们把 左端点记做i,区间长度改为j呢 那么f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1];

    所有我们在预处理的时候,我们不妨先枚举区间长度j,再枚举区间左端点i。

    只要能保证i+(1<<j)-1≤n,那么我们便可以将各种区间给预处理出来。

    (偷luogu的图)

    那么预处理完了 怎么才能做到o(1)查询呢

    因为无法做到输入的l与r一定是2的次方数 所以无法做到精准查询 不过我们看上图 可以发现 要查询的区间可以通过两个区间的并集来得到

    所以我们有代码

    int check(int l, int r)
    {
        int z = log2(r - l + 1);
        return min(f[l][z], f[r - (1 << z) + 1][z]);
    }

    这样我们就做到了o(1)的查询

    人十我百 人百我万
  • 相关阅读:
    常见HTTP状态(304,)
    面试错题集
    从零构建以太坊(Ethereum)智能合约到项目实战——学习笔记1
    windows 以太坊开发框架Truffle环境搭建
    Ollydbg使用问题汇总
    网络攻防实战技术之——缓冲区溢出篇
    如何批量删除.svn文件
    树莓派安装nextcloud、Seafile
    汇编语言从入门到精通-5微机CPU的指令系统2
    kali安装vm tools正确操作
  • 原文地址:https://www.cnblogs.com/bestcoder-Yurnero/p/11011868.html
Copyright © 2020-2023  润新知