zoukankan      html  css  js  c++  java
  • 学习笔记——ST表

    作用:

    给定一个数列 ai O(nlogn) 预处理 O(1) 查询区间最值

    实现:

    定义f(i,j) 为ai开始,包括ai的连续2^j个元素的最值
    下面以最大值为例:
    f(i,j)表示max{ak}(k∈[i,i+2^j)).
    利用倍增:
    f[i][j]=

    {aimax(f[i][j1],f[i+2j1][j1])j=0j>0{aij=0max(f[i][j−1],f[i+2j−1][j−1])j>0


    区间([L,R])求值:
    把区间看做[L,L+2^j-1]和[R-2^j+1,R]两部分
    虽然有重叠(或者说相交)但可以忽略(因为要求最值)
    其中 j=⌊log₂(R−L+1)⌋
    所以 f[i][j]=max(f[L][j],f[R-2^j+1][j]);

    code:

    //By Menteur_Hxy
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<ctime>
    using namespace std;
    
    const int MAX=2000;
    int n,m,x,y;
    int a[MAX+5],lg[MAX+5],maxn[MAX+5][MAX+5];
    
    void solve(int *x) {
        for(int i=1;i<=n;i++) {
            lg[i]=lg[i-1];
            if(1<<lg[i-1]+1==i) lg[i]++;
            //lg[i]=((i & (i-1))==0) ? lg[i-1]+1 : lg[i-1];
        }
            for(int j=1;j<=lg[n];j++)
                for(int i=1;i+(1<<j)-1<=n;i++) 
                    maxn[i][j]=max(maxn[i][j-1],maxn[i+1<<(j-1)][j-1]);
    
    }
    
    int askm(int l,int r) {
        int k=lg[r-l+1];
        return max(maxn[l][k],maxn[r-(1<<k)+1][k]);
    }
    
    int main() {
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
            maxn[i][0]=a[i];
        }
        solve(a);
        for(int i=1;i<=m;i++) {
            scanf("%d %d",&x,&y);
            printf("%d
    ",askm(x,y));
        }
        return 0;
    }
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    Angular2+学习第1篇 简介
    JS:ES5数组基本操作
    git常用操作命令
    URL-Routing
    uid-datepicker
    元素隐藏 css
    Angular2+学习第2篇 cli 环境搭建过程
    DRF 07
    DRF小练习 04
    DRF小练习 02
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9248019.html
Copyright © 2011-2022 走看看