zoukankan      html  css  js  c++  java
  • ST表

    st表

    ST表类似树状数组,线段树这两种算法,是一种用于解决RMQ(Range Minimum/Maximum Query,即区间最值查询)问题的离线算法。

    st表的预处理时间复杂度为(O(logn)),查询为(O(1)),而线段树的查询为(O(logn))

    我们定义:(dp[i][j])为 i 到 (i+2^j-1)这个区间内的最值(这里和下面假设是最大值),所以状态转移方程为:

    (dp[i][j]=max(dp[i][j-1],dp[i+1<<(j-1)][j-1]))

    其代码也很好理解:

    void init_rmq()
    {
        for (int i=1;i<=n;++i)
            dp[i][0]=arr[i];
        for (int j=1;(1<<j)<=n;++j)         //先循环区间,原理同区间dp
            for (int i=1;i+(1<<j)-1<=n;++i)
                dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
        //注意优先级大小,一定要打括号
    }
    int query(int l,int r)
    {
        int k=log2(r-l+1);				//log2不能写作log...
        return max(dp[l][k],dp[r-(1<<k)+1][k]);
    }
    

    AC代码:求每m个区间中的最小值(RQM版)

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn=1e6+10;
    int arr[maxn],dp[maxn][20];
    int n,m;
    void init()
    {
    	for(int i=1;i<=n;++i)
    		dp[i][0]=arr[i];
    	for(int j=1;(1<<j)<=n;++j)
    		for(int i=1;i+(1<<j)-1<=n;++i)
    			dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    }
    int query(int l,int r)
    {
    	int k=log2(r-l+1);
    	return min(dp[l][k],dp[r-(1<<k)+1][k]);
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i)	scanf("%d",&arr[i]);
    	init();
    	for(int i=1;i<=n-m+1;++i)
    		printf("%d
    ",query(i,i+m-1));
    	system("pause");
    }
    
  • 相关阅读:
    事务
    一、python 基础之基础语法
    二、python 中五种常用的数据类型
    三、python函数详解
    四、 面向对象(一)
    五、面向对象(二)——继承与重写
    六、异常处理、日志打印、文件操作
    scrapy(一):基础用法
    # scrapy(二):get请求
    scrapy(三):post请求
  • 原文地址:https://www.cnblogs.com/StungYep/p/12253938.html
Copyright © 2011-2022 走看看