zoukankan      html  css  js  c++  java
  • 【总结】st表

    对于一类问题:

    RMQ(Range Minimum/Maximum Query) 区间最值查询

    给一个序列a[1],a[2],…,a[n],每次查询一个区间的最小值

    我们可以用线段树解决,也可以一种更简单的数据结构st表来解决

    st表相较于线段树而言时间复杂度更低,代码也更简洁

    但是st表所能解决的问题非常有限

    一句话总结就是:st表能解决的问题线段树一定能解决,但线段是能做到st表做不到

    算法实现

    运用倍增的思想,我们令(f[i] [k])数组表示区间([i,i + 2^k-1])中的最小值

    (f[i] [0]= a[i])

    (f[i] [k-1] = min(f[i] [k],f[i + (1<< k)] [k]))

    查询时给了一个区间[l, r],我们找一个最大的j满足(2^j <= r - l + 1)

    于是我们可以用(f[l] [j])(f[r – 2^j + 1] [j])来覆盖这个区间,得到最小值

    也即(answer = min(f[l] [j], f[r – (1 << j) + 1] [j]))

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,l,r;//这是个st表emm可我不会 
    int Max[100001][22];
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&Max[i][0]);//读入emm他到他本身的区间最大值就是他w
    	} 
    	for(int j=1;j<=21;j++){
    		for(int i=1;i+(1<<j)-1<=n;i++){
    			Max[i][j]=max(Max[i][j-1],Max[i+(1<<(j-1))][j-1]);
    		}
    	}
    	for(int i=1;i<=m;i++){
    		scanf("%d%d",&l,&r);
    		int a=log2(r-l+1);
    		printf("%d
    ",max(Max[l][a],Max[r-(1<<a)+1][a]));
    	}
    	return 0;
    }
    
  • 相关阅读:
    [HAOI2006] 数字序列
    [HAOI2012] 外星人
    [HAOI2012] 高速公路
    [HAOI2007] 覆盖问题
    [HAOI2007] 分割矩阵
    [HAOI2007] 上升序列
    牛客练习赛58 D 迷宫
    牛客练习赛58 F XOR TREE
    牛客练习赛58 E 最大GCD
    牛客练习赛58 C 矩阵消除游戏
  • 原文地址:https://www.cnblogs.com/huixinxinw/p/12256781.html
Copyright © 2011-2022 走看看