题目链接:
http://acm.nyist.net/JudgeOnline/problem.php?pid=119
1 #include <iostream>
2 #include <cmath>
3 #include <cstdio>
4 using namespace std;
5 #define maxn 100001
6
7 int ma[maxn][17], mi[maxn][17], N, Q;
8 //状态转移方程为:
9 //dp[j][i] = max(dp[j][i-1], dp[j+(1<<(i-1))][i-1]);
10 void rmq_init(){
11 int i, j, t;
12 int m = int(log(double(N))/log(2.0));
13 for(i = 1; i <= m; ++i)
14 for(j = 1; j <= N; ++j){
15 t = j + (1 << (i - 1));
16 if(t <= N){
17 ma[j][i] = max(ma[j][i-1], ma[t][i-1]);
18 mi[j][i] = min(mi[j][i-1], mi[t][i-1]);
19 }
20 else{
21 ma[j][i] = ma[j][i-1];
22 mi[j][i] = mi[j][i-1];
23 }
24 }
25 }
26
27 int query(int m, int n)
28 {
29 int t = int(log(double(n - m + 1))/log(2.0));
30 int a = max(ma[m][t], ma[n - (1<<t) + 1][t]); //区间最大值
31 int b = min(mi[m][t], mi[n - (1<<t) + 1][t]); //区间最小值
32 return a - b;
33 }
34
35 int main()
36 {
37 int i, m, n;
38 while(scanf("%d%d",&N, &Q) != EOF){
39 for(i = 1; i <= N; ++i){ //初值(dp[i][0])
40 scanf("%d",&ma[i][0]);
41 mi[i][0] = ma[i][0];
42 }
43 rmq_init();
44 for(i = 0; i < Q; ++i)
45 {
46 scanf("%d%d",&m, &n);
47 printf("%d\n",query(m, n));
48 }
49 }
50 return 0;
51 }