zoukankan      html  css  js  c++  java
  • 浅谈ST表

    浅谈ST表

    先丢个板子:

    https://www.luogu.org/problemnew/show/P3865

    基本思路:

    ST表运用的是 倍增+动态规划 的思想,预处理的时间复杂度是O(nlogn),查询是O(1)的。

    ST表的存储是用的二位数组st [ i ] [ j ] ,表示以第I位开头,长度为2^J的区间。

    题目:给定一个长度为 N 的数列,和 M 次询问,求出每一次询问的区间内数字的最大(小)值。

    这里我们只谈最大值,因为最小值也是同样的道理,把函数Max改成Min就可以了。

    具体实现:

    输入:把长度为N的序列存到ST[ i ] [ 0 ] 中,因为以i开头长度为2^0就是i。

    预处理:动态规划解决,st[ j ][ i ]=max(st[ j ][ i-1],st[ j+(1<<( i-1 ))] [i-1]);

    当前区间最大值由两个子区间最大值得来。

    输出:从两个重叠的子区间取最大值。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int n,stb[100005][22],m;//以I开头,长度为2^j的区间
    void init()
    {
        for(register int i=1;i<=21;i++)
        for(register int j=1;(j+(1<<i)-1)<=n;j++)
        stb[j][i]=max(stb[j][i-1],stb[j+(1<<(i-1))][i-1]);
    }
    void query(int l,int r)
    {
        int k=log2(r-l+1);
        printf("%d
    ",max(stb[l][k],stb[r-(1<<k)+1][k]));
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(register int i=1;i<=n;i++)
        scanf("%d",&stb[i][0]);
        init();
        for(register int i=1;i<=m;i++)
        {
        int l,r;
        scanf("%d%d",&l,&r);
        query(l,r);
        }
        return 0;
    }

    我比较懒,所以代码里注释极少...

  • 相关阅读:
    中国天气网数据获取
    雪球数据的定时爬取
    爬虫下载中间件
    简书全站CrawlSpider爬取 mysql异步保存
    房天下新房和二手房
    多线程
    selenium+chromdriver 动态网页的爬虫
    汽车之家下载文件和图片
    re正则
    532.数组中的K-diff数对
  • 原文地址:https://www.cnblogs.com/sky-zxz/p/9396467.html
Copyright © 2011-2022 走看看