pku 3264
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int N=5e4+7;
int a[N];
int n;
int mx[N][20],mi[N][20];
void rmq()//預處理O(nlogn)
{
for(int i=1; i<=n; i++)
mx[i][0]=a[i],mi[i][0]=a[i];//初始狀態
for(int j=1; (1<<j)<=n; j++)//兩層for不能反,自己思考一下
for(int i=1; i+(1<<j)-1<=n; i++)
{
mi[i][j]=min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]);
mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]);
}
}
int query(int l,int r)//查詢 O(1)
{
int k=trunc(log2(r-l+1));//即取整,去尾
// trunc(number,num_digits)
// Number 需要截尾取整的數字。
// Num_digits 用於指定取整精度的數字。Num_digits 的默認值爲 0。
return (max(mx[l][k],mx[r-(1<<k)+1][k])-min(mi[l][k],mi[r-(1<<k)+1][k]));//預處理已經完全 可直接返回
}
int main()
{
int q;
while(~scanf("%d%d",&n,&q))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
rmq();
for(int i=0;i<q;i++)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r));
}
}
}
RMQ算法不能修改
dp[i][j] 代表從 i 到 i+2^j-1 的最大/小值
預處理:dp[i][0]爲最初始
查詢 l 到 r 的最值:k是小於(r-l+1)最小的2的冪次那麼l到l+(1<