zoukankan      html  css  js  c++  java
  • 【模板】st表

    利用了倍增的思想,st[i][j]表示[i,  i + 2j - 1]的区间内的最(大、小)值

    自然st[i][0]存的就是序列中的第i个数,区间[l, r]的长度为log2(r - l + 1)

    预处理:

    处理每个为2的倍数的区间:

    区间 [i, i + 2j] 的值为区间 [i, i + 2j - 1] 和区间 [i + 2j - 1, i + 2j] 的最值

    复杂度O(n log2 n)

    关于每次取log2,用cmath里的函数会很慢(保留了小数)

    所以可以预处理出log2(i)的整数值 

    for(int i = 0; (1 << i) <= n; i++)
        Log2[1 << i] = i;
    for(int i = 1; i <= n; i++)
        if(!Log2[i]) Log2[i] = Log2[i - 1];
    处理log2

    查询[l, r]区间的最值:

    取区间[l, l + 2k - 1]和区间[r - 2k + 1, r]的最值

    复杂度O(1)

    其实蛮好理解的...QwQ

    【代码:】

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 using namespace std;
     5 
     6 const int MAXN = 1e5 + 1, MAXM = 1e6 + 1;
     7 const int K = 18;
     8 
     9 int n, m;
    10 int a[MAXN], st[MAXN][K], Log2[MAXN];
    11 
    12 int Query(int l, int r) {
    13     int x = Log2[r - l + 1];
    14     return max(st[l][x], st[r - (1 << x) + 1][x]);
    15 }
    16 int main() {
    17     scanf("%d%d", &n, &m);
    18     for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    19     for(int i = 1; i <= n; i++) st[i][0] = a[i];
    20     for(int j = 1; j <= K; j++) {
    21         for(int i = 1; i + (1 << j) - 1 <= n; i++)
    22             st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
    23     }
    24     for(int i = 0; (1 << i) <= n; i++)
    25         Log2[1 << i] = i;
    26     for(int i = 1; i <= n; i++)
    27         if(!Log2[i]) Log2[i] = Log2[i - 1]; 
    28     while(m--) {
    29         int l, r;
    30         scanf("%d%d", &l, &r);
    31         printf("%d
    ", Query(l, r));
    32     }
    33 }
  • 相关阅读:
    weblogic 正常启动页面还是404
    oracle awr 生成
    jre 修改timezone 夏令时冬令时问题
    apache 2.4 配置loadbalance
    plsq 调试存储过程
    Windows怎么命令行修改文件权限
    Windows上面挂载NFS共享
    linux sar命令详解
    Tomcat Connector connectionTimeout含义和验证
    c++STL系列之Set
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9021574.html
Copyright © 2011-2022 走看看