가장 값 범위 RMQ 문의 얻기
추천 블로그
좋은 설명 : https://blog.csdn.net/qq_41311604/article/details/79900893
세부 사항의 일부를 설명 : https://blog.csdn.net/xi__long/article/details/36933515
개요
RMQ
(Range Minimum/Maximum Query)
, 이다, 간격 값 대부분의 질의 . RMQ 알고리즘은 일반적으로 긴 전처리 시간 복잡도로 만든O(nlogn)
다음, 수 있고,O(1)
질의 당 처리 시간 내에.
주로 해결하기 : 당신을 포함하여 배열, 줄 N
번호, 지금 당신은 당신이 간격으로 여러 번 물어 [l,r]
, 얼마나 많은 가장 값이 간격에서 당신을 물어?
템플릿 코드
void rmq_init() //RMQ初始化
{
for(int i=1; i<=n; i++)
dp[i][0]=arr[i];
for(int j=1; (1<<j)<=n; j++)
for(int i=1; i+(1<<j)-1<=n; i++)
dp[i][j]=min(dp[i][j-1], dp[i+(1<<j-1)][j-1]); //i + (1 << (j - 1))
//左移操作符的优先级小于加号的优先级
}
//
int rmq(int l, int r)
{
int k=log2(r-l+1);
return min(dp[l][k], dp[r-(i<<k)+1][k]);
}
항목 제목
POJ 3264
제목의 의미하는 것은 다음 당신에게 일련의 숫자를 줄 주어진 간격으로 최대 및 최소를 요청 말한다.
1, 트리 라인이 될 수 템플릿의 제목되지만, RMQ
적은 코드는.
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const double esp=1e-6;
const int inf=0x3f3f3f3f;
const int MAXN=5e4+7;
int num[MAXN], madp[MAXN][20], midp[MAXN][20];
int n, q;
void init()
{
for(int i=1; i<=n; i++)
{
madp[i][0]=num[i];
midp[i][0]=num[i];
}
for(int j=1; (1<<j) <=n; j++)
for(int i=1; i+(1<<j)-1<=n; i++)
{
madp[i][j]=max(madp[i][j-1], madp[i+(1<<j-1)][j-1]);
midp[i][j]=min(midp[i][j-1], midp[i+(1<<j-1)][j-1]);
}
}
int rmq_max(int l, int r)
{
int k=log2(r-l+1);
return max(madp[l][k], madp[r-(1<<k)+1][k]);
}
int rmq_min(int l, int r)
{
int k=log2(r-l+1);
return min(midp[l][k], midp[r-(1<<k)+1][k]);
}
int main()
{
while(scanf("%d%d", &n, &q)!=EOF)
{
for(int i=1; i<=n; i++)
{
scanf("%d",&num[i]);
}
init();
int l, r;
for(int i=1; i<=q; i++)
{
scanf("%d%d",&l, &r);
printf("%d\n", rmq_max(l, r)-rmq_min(l, r));
}
}
return 0;
}