【hiho】16 RMQ-ST算法【RMQ-ST算法】

传送门:RMQ-ST算法

RMQ(Range Minimum/Maximum Query)区间范围最值查询问题

题意

求指定区间值最小的元素

思路

其实就是二分法的思路,统计所有长度为2的非负整数次幂的区间。

然后将所求转化到在包含的几个区间之中寻找最小值。

Online AC Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <queue>
#include <set>
using namespace std;

#define FOR(i, s, t ) for( int i = s; i < t; ++i )
#define REP( i, s, t ) for( int i = s; i <= t; ++i )
#define eps 1e-8
#define inf 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
#define pii pair<int, int >
#define MP make_pair
#define lson id << 1, l, m
#define rson id << 1 | 1, m + 1, r
#define maxn ( 1000000 + 10 )
#define maxe ( 200000 + 100 )

int d[maxn][30],num[maxn];

void rmq_init ( int n ){
    for( int i = 0; i < n; i++ ) d[i][0] = num[i];
    for( int j = 1; (1<<j) <= n; j++ )
        for( int i = 0; i + (1<<j ) - 1 < n; i ++ )
            d[i][j] = min( d[i][j-1], d[i+(1<<(j-1))][j-1] );
}

int rmq ( int l, int r ){
    int k = 0;
    while( ( 1 << (k+1) ) <= ( r - l + 1 ) ) k++ ;
    return min( d[l][k], d[r - (1<<k) + 1][k] );
}

int main () {
    int n;
    scanf("%d", &n );
    FOR( i,0 ,n ) scanf("%d", num+i );
    rmq_init( n );

    int m ;
    scanf("%d", &m );
    int l, r;
    while( m-- ) {
        scanf("%d%d", &l, &r );
        --l, --r;
        printf("%d\n", rmq( l, r ) ) ;
    }
}

原文地址:https://www.cnblogs.com/shengwang/p/9768696.html

时间: 2024-11-05 22:06:27

【hiho】16 RMQ-ST算法【RMQ-ST算法】的相关文章

倍增思想到ST表RMQ

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 36864   Accepted: 17263 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer Joh

K-th occurrence(后缀树组+划分树+ST表+RMQ+二分)

2019CCPC网络选拔赛1003 HDU6704 题目大意: T个测试样例.一个长度为N的字符串S,之后Q个[l,r,k],表示一个子串S[l,r],求出第k个该子串的下标.起始坐标为1.不存在输出-1. 数据范围:1≤T≤20,  1≤N≤105,  1≤Q≤105,  1≤l≤r≤N,  1≤k≤N,  |S|=N; 赛后补题.参考题解说后缀树组+划分树+ST表+二分. 比赛的时候只会后缀树组不会划分树,赛后仔细想,觉得后缀数组可以,然而并不,会TLE. 补提的时候先是采用后缀树组+划分树

算法笔记--st表

概述:用倍增法求区间最值的离线算法,O(nlogn)预处理,O(1)访问. 预处理: 状态:st[i][j]:[i,i+2^j)之间的最值 状态转移:如果j等于0,st[i][j]=0 如果j大于0,st[i][j]=max(st[i][j-1],st[i+2^(j-1)][j-1])或st[i][j]=min(st[i][j-1],st[i+2^(j-1)][j-1]) 访问: 求[l,r]区间里的最值 k=floor(log(r-l+1)) ans=max(st[l][k],st[r-2^k

【强连通分量】tarjan算法及kosaraju算法+例题

阅读前请确保自己知道强连通分量是什么,本文不做赘述. Tarjan算法 一.算法简介 Tarjan算法是一种由Robert Tarjan提出的求有向图强连通分量的时间复杂度为O(n)的算法. 首先我们要知道两个概念:时间戳(DFN),节点能追溯到的最早的栈中节点的时间戳(LOW).顾名思义,DFN就是在搜索中某一节点被遍历到的次序号(dfs_num),LOW就是某一节点在栈中能追溯到的最早的父亲节点的搜索次序号. Tarjan算法是基于深度优先搜索的算法.在搜索过程中把没有Tarjan过的点入栈

【C/C++学院】0907-象棋五子棋代码分析/寻找算法以及排序算法

象棋五子棋代码分析 编译代码报错: 错误 1 error MSB8031: Building an MFC project for a non-Unicode character set is deprecated. You must change the project property to Unicode or download an additional library. See http://go.microsoft.com/fwlink/p/?LinkId=286820 for mo

最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind

最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小支撑树(minimum spanning tree)算法.给定一个无向图G,并且它的每条边均权值,则MST是一个包括G的所有顶点及边的子集的图,这个子集保证图是连通的,并且子集中所有边的权值之和为所有子集中最小的. 本节中介绍三种算法求解图的最小生成树:Prim算法.Kruskal算法和Boruvk

图论专题小结:网络流算法之ISAP算法

ISAP算法 ISAP(Improved Shortest Augument Path)算法是改进版的SAP算法,如果对效率要求很高的时候,可以用该算法. (1)概述:算法基于这样的一个事实:每次增广之后,任意结点到汇点(在残余网络中)的最短距离都不会减小.这样,我们可以利用d[i[表示结点i到汇点的距离的下界.然后再增广过程当中不断地修改这个下界.增广的时候和Dinic算法类似,只允许沿着d[i]==d[j]+1的弧(i,j)走. 不难证明,d[i[满足两个条件:(1)d[t]=0;(2)对任

floyd判环算法(龟兔赛跑算法)

floyd判环算法(龟兔赛跑算法) 注意,这个算法是用来判断一条链+一条环的图,环的长度或者环与链的交界处的,所以此floyd非彼floyd(虽然都是一个人想出来的). (图不是我的) 如果只要求环的长度的话,只要让h和t相遇,然后再让h跑一圈,同时计算出步数就行了. 如果要算出链和环的交界点呢?首先,指针h和t同时从S出发,速度一个为2,一个为1(不要在意细节).当t走到链和环的交界点时,在右边的ht的距离等于st的距离.设st的距离为x,在左边的ht距离为y,那么环的长度就是x+y.现在让h

BF算法与KMP算法

BF(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符:若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果. BF算法实现: 1 int BF(char S[],char T[],int pos) 2 {//c从第pos位开始搜索匹配 3 int i=pos,j=0; 4 while(S[i+j]!='\0'&&T[j]!='\0')