http://poj.org/problem?id=3264
题意:求某个区间最大值与最小值的差。
RMQ:利用动态规划的思想求区间最大值与最小值。又称为ST在线算法。
主要思想:
F[i,j]表示从i开始,连续的 2^j个数中的最值。
1. 预处理:F[i, j]=max(F[i,j-1], F[i + (1<<(j-1)),j-1])。
2. 查询:找到i,j中间的k值,k = log2(j-i+1)。然后 ans = min/max(F[i,k],F[j-(1<< k)+1 , k];
模板Style:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 50000 + 100;
int dp_max[N][20];
int dp_min[N][20];
void RMQ(int n)
{
for(int j=1;j<20;j++)
{
for(int i=1;i<=n;i++)
{
if(i+(1<<(j-1))<=n)//!!!
{
dp_max[i][j] = max(dp_max[i][j-1],dp_max[i+(1<<(j-1))][j-1]);
dp_min[i][j] = min(dp_min[i][j-1],dp_min[i+(1<<(j-1))][j-1]);
}
}
}
return;
}
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
int x;
for(int i=1;i<=n;i++)
scanf("%d",&x),dp_max[i][0] = dp_min[i][0] = x;
RMQ(n);
while(m--)
{
int l,r;
scanf("%d %d",&l,&r);
int k = log10(r-l+1.0)/log10(2.0);//!!!
int ans_max = max(dp_max[l][k],dp_max[r-(1<<k)+1][k]);
int ans_min = min(dp_min[l][k],dp_min[r-(1<<k)+1][k]);
cout<<ans_max - ans_min<<endl;
}
}
return 0;
}
神模板加神题解:
http://blog.csdn.net/liang5630/article/details/7917702
http://blog.csdn.net/liang5630/article/details/7917706
博主很懒,什么都不想留下..