1. 程式人生 > >RMQ——蒜頭君的玩具娃娃(區間範圍最大值-區間範圍最小值)

RMQ——蒜頭君的玩具娃娃(區間範圍最大值-區間範圍最小值)

mes default bsp lose 格式 baseline 自己的 con using

蒜頭君有 N 個玩具娃娃,編號依次從 1 到 N,每個娃娃都有自己的高度值。蒜頭君想考考聰明的你,蒜頭君會有 Q 次詢問,每次詢問給定兩個整數 A 和 B,求問編號 A 和編號 B 之間(包含編號 A 和編號 B),高度最大的娃娃和高度最小的娃娃差是多少。

輸入格式

第一行輸入兩個正整數 N,Q(N50,000,Q200,000)。代表 N 個玩具娃娃,以及蒜頭君的 Q 次 詢問。

接下來輸入 N 行,每行輸入一個正整數 h?i??(1h?i??1,000,000),表示第i 個玩具的高度。

再接下來輸入 Q 行,每行輸入兩個正整數 A 和 B,表示一共有 Q 次詢問,每次詢問的區間 [A,B](1ABN)。

輸出格式

輸出一共 Q 行,每行輸出一個整數,表示第 i 詢問的結果,即區間內高度最大的娃娃和高度最小的娃娃差。

樣例輸入

5 2
3
1
5
2
7
2 3
1 5

樣例輸出

4
6

RMQ模板題
l[i][j]表示以i為起點的區間大小為2^j的區間中的最大值。可以用遞推求出。
註意‘<<’的優先級沒有‘-’高
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=50000+10;
int a[maxn];
int n;
int s[maxn][50];//存儲最小值
int l[maxn][50];//存儲最大值
void rmg_init()
{
    for(int i=0;i<n;i++)
        s[i][0]=l[i][0]=a[i];
    for(int j=1;(1<<j)<=n;j++)//先枚舉區間範圍
        for(int i=0;i<n;i++)
    {
        s[i][j]=min(s[i][j-1],s[i+(1<<j-1)][j-1]);//<<沒有-的優先級高
        l[i][j]=max(l[i][j-1],l[i+(1<<j-1)][j-1]);
    }
}
int query(int x,int y)
{
    int fl,fs;
    int k=0,t=y-x+1;
    while(1<<k<=t)
        k++;
    k--;
    fs=min(s[x][k],s[y-(1<<k)+1][k]);
    fl=max(l[x][k],l[y-(1<<k)+1][k]);
    return fl-fs;
}
int main()
{
    int q;
    cin>>n>>q;
    for(int i=0;i<n;i++)
        cin>>a[i];
    rmg_init();
    while(q--)
    {
        int x,y;
        cin>>x>>y;
        int ans=query(x-1,y-1);
        cout<<ans<<endl;
    }
    return 0;
}

  

RMQ——蒜頭君的玩具娃娃(區間範圍最大值-區間範圍最小值)