zoukankan      html  css  js  c++  java
  • ST表模板

    引入:

    (RMQ) 问题(区间最值)中,有一个著名的 (ST) 算法。原理是通过倍增实现。给定一个长度 (N) 的数列,(ST) 算法在经过 (O(NogN)) 的预处理后,能够以 (O(1)) 的复杂度在线查询下标 (l o r) 之间的数的最值。

    原理:

    (F[i,j]) 表示数列 (A) 中下标在子区间 ([i,i+2^j-1]) 里的数的最值。边界条件显然是 (F[i,0]=A[i])
    在递推时,我们让子区间成倍增长,状态转移 (F[i,j]=max(F[i,j-1],F[i+2^{j-1},j-1])),即长度为 (2^j) 的子区间的最大值是左右两个半区间的最值中的一个。

    以最小值为例:

    void init()
    {
        for(int i=1;i<=n;i++) f[i][0]=a[i];
        int t=log(n)/log(2)+1;
        for(int j=1;j<t;j++)
            for(int i=1;i<=n-(1<<j)+1;i++)
                f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    }
    

    当询问 ([l,r]) 的最值时,先计算一个 (k),使得 (2^k<r-l+1<2^{k+1})
    那么从 (l) 开始的 (2^k) 的区间和以 (r) 为结尾的 (2^k) 的区间一定覆盖了整个 ([l,r]) 的区间。

    int ask(int l,int r)
    {
        int k=log(r-l+1)/log(2);
        return min(f[l][k],f[r-(1<<k)+1][k]);
    }
    
  • 相关阅读:
    oracel 复制A列的内容到列
    视图转为表
    面向对象
    银弹效应
    解决linux删除文件后空间没有释放问题
    HttpAnalyzerStdV7安装教程
    HttpUploader6.2-process版本
    Chrome浏览器控件安装方法
    Firefox浏览器控件安装方法
    通达OA整合教程
  • 原文地址:https://www.cnblogs.com/Suiyue-Li/p/12588619.html
Copyright © 2011-2022 走看看