RMQ——蒜頭君的玩具娃娃(區間範圍最大值-區間範圍最小值)
阿新 • • 發佈:2017-07-24
mes default bsp lose 格式 baseline 自己的 con using
蒜頭君有 N 個玩具娃娃,編號依次從 1 到 N,每個娃娃都有自己的高度值。蒜頭君想考考聰明的你,蒜頭君會有 Q 次詢問,每次詢問給定兩個整數 A 和 B,求問編號 A 和編號 B 之間(包含編號 A 和編號 B),高度最大的娃娃和高度最小的娃娃差是多少。
輸入格式
第一行輸入兩個正整數 N,Q(N≤50,000,Q≤200,000)。代表 N 個玩具娃娃,以及蒜頭君的 Q 次 詢問。
接下來輸入 N 行,每行輸入一個正整數 h?i??(1≤h?i??≤1,000,000),表示第i 個玩具的高度。
再接下來輸入 Q 行,每行輸入兩個正整數 A 和 B,表示一共有 Q 次詢問,每次詢問的區間 [A,B](1≤A≤B≤N)。
輸出格式
輸出一共 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——蒜頭君的玩具娃娃(區間範圍最大值-區間範圍最小值)