• [算法模板]ST表


    [算法模板]ST表

    ST表和线段树一样,都能解决RMQ问题(范围最值查询-Range Minimum Query)。

    我们开一个数组数组(f[maxn][maxnlog_2])来储存数据。

    定义(f[i][j])代表从(i)开始的(2^{j})位这个区间的最大值。

    初始化

    因为(f[i][0]=a[i]),所以有:

    [f[i][j]=max(f[i][j-1],f[i+2^{j-1}][j-1]) ]

    通过这个转移方程即可构造出(f)

    查询

    查询区间([l,r])的最大值。

    (k=log _2(l-r+1)),那么很容易想明白:

    [ans=max(f[l][k],f[r-2^k+1][2^k]) ]

    注意定义(f)的时候,(i)是包含在(2^k)里面的,所以可能会+1/-1。

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define maxn (int)(1e5+1000)
    int a[maxn],f[maxn][21],n,m;
    void init(){
    	for(int i=1;i<=n;i++)f[i][0]=a[i];
    	for(int j=1;j<=20;j++){
    		for(int i=1;i-1+(1<<(j-1))<=n;i++){
    			f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    		}
    	}
    	return;
    }
    int query(int l,int r){
    	int k=log2(r-l+1);
    	return max(f[l][k],f[r-(1<<(k))+1][k]);
    }
    int main(){
    	//freopen("in","r",stdin);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    	}
    	init();
    	for(int i=1;i<=m;i++){
    		int l,r;scanf("%d%d",&l,&r);
    		printf("%d
    ",query(l,r));
    	}
    	return 0;
    }
    
  • 相关阅读:
    你真的会写二分查找吗
    深入理解C++对象模型
    python监控ip攻击,服务器防火墙
    python操作redis
    python操作mysql
    jmeter_linux下运行
    chales抓包,模拟异常情况
    python正则表达式
    python-笔记(六)模块操作以及常用模块简介
    fpython-笔记(五)装饰器、匿名函数
  • 原文地址:https://www.cnblogs.com/GavinZheng/p/10831563.html
Copyright © 2020-2023  润新知