1. 程式人生 > >rmq問題模板處理

rmq問題模板處理

query ini -c long -o 取出 es2017 string dia

rmq問題:

先貼一下定義

範圍最值查詢

維基百科,自由的百科全書

範圍最值查詢(Range Minimum Query),是針對數據集的一種條件查詢。若給定一個數組 A[1, n],範圍最值查詢指定一個範圍條件 i 到 j,要求取出 A[i, j] 中最大/小的元素。

若 A = [3, 5, 2, 5, 4, 3, 1, 6, 3],條件為 [3, 8] 的範圍最值查詢返回 1,它是子數組 A[3, 8] = [2, 5, 4, 3, 1, 6]中最小的元素。

通常情況下,數組 A 是靜態的,即元素不會變化,例如插入、刪除和修改等,而所有的查詢是以在線的方式給出的,即預先並不知道所有查詢的參數。

RMQ 問題有預處理

範圍最值查詢問題(RMQ)與最近公共祖先 (圖論)(LCA)問題有直接聯系,它們可以互相轉化。RMQ 的算法常常應用在嚴格或者近似子串匹配等問題的處理中。

暴力的去查詢,期望復雜度是O(N)查詢,O(N)處理

用線段樹維護,期望復雜度O(logN)查詢,O(N)處理

當然還有更優秀的ST算法(稀疏表算法)

技術分享----以上均轉自維基百科

相對比線段樹維護,st算法可以做到O(1)回答,復雜度有了不少的優化

#pragma GCC optimize("O2")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<limits.h>
#include<ctime>
#define N 100001
typedef long long ll;
const int inf=0x3fffffff;
const int maxn=2017;
using namespace std;
inline int read()
{
    int f=1,x=0;char ch=getchar();
    while(ch>‘9‘|ch<‘0‘)
    {
        if(ch==‘-‘)
        f=-1;
        ch=getchar();
    }
    while(ch<=‘9‘&&ch>=‘0‘)
    {
        x=(x<<3)+(x<<1)+ch-‘0‘;
        ch=getchar();
    }
    return f*x;
}
int rmq[30][N],lg[N];

void init(int n)
{
	for(int i=2;i<=n;i++) 
    lg[i]=lg[i>>1]+1; 
    for(int i=1;i<=lg[n];i++) 
    for(int j=1;j<=n+1-(1<<i);j++) 
    rmq[i][j]=min(rmq[i-1][j],rmq[i-1][j+(1<<(i-1))]); 
}

int rminq(int l,int r)
{
	if(l>r)swap(l,r);
	int x=lg[r-l+1]; 
	return min(rmq[x][l],rmq[x][r+1-(1<<x)]);
}

int main() 
{ 
	int n=read(),m=read();
    for(int i=1;i<=n;i++) 
    rmq[0][i]=read();
    for(int i=1;i<=m;i++) 
    { 
        int l=read(),r=read(); 
        printf("%d\n",rminq(l,r)); 
    } 
}

rmq問題模板處理