莫队 WD

关于莫对的博客    http://blog.csdn.net/liang5630/article/details/7917702

 1 /*
 2 RMQ 最近公共祖先,
 3 dfs序列 区间最大值 
 4 */
 5 #include <cstdio>  
 6 #include <cstring>  
 7 #include <cmath>  
 8 #include <iostream>  
 9 using namespace std;  
10 const int MAXN = 100117;  
11 int n,query;  
12 int num[MAXN];  
13   
14 int F_Min[MAXN][20],F_Max[MAXN][20];  
15   
16 void Init()  
17 {  
18     for(int i = 1; i <= n; i++)  
19     {  
20         F_Min[i][0] = F_Max[i][0] = num[i];  
21     }  
22   
23     for(int i = 1; (1<<i) <= n; i++)  //按区间长度递增顺序递推  
24     {  
25         for(int j = 1; j+(1<<i)-1 <= n; j++)  //区间起点  
26         {  
27             F_Max[j][i] = max(F_Max[j][i-1],F_Max[j+(1<<(i-1))][i-1]);  
28             F_Min[j][i] = min(F_Min[j][i-1],F_Min[j+(1<<(i-1))][i-1]);  
29         }  
30     }  
31 }  
32   
33 int Query_max(int l,int r)  
34 {  
35     int k = (int)(log(double(r-l+1))/log((double)2));  
36     return max(F_Max[l][k], F_Max[r-(1<<k)+1][k]);  
37 }  
38   
39 int Query_min(int l,int r)  
40 {  
41     int k = (int)(log(double(r-l+1))/log((double)2));  
42     return min(F_Min[l][k], F_Min[r-(1<<k)+1][k]);  
43 }  
44   
45 int main()  
46 {  
47     int a,b;  
48     scanf("%d %d",&n,&query);
49     for(int i = 1; i <= n; i++)  
50         scanf("%d",&num[i]);  
51     Init();  
52     while(query--)  
53     {  
54         scanf("%d %d",&a,&b);  
55         printf("区间%d到%d的最大值为:%d
",a,b,Query_max(a,b));  
56         printf("区间%d到%d的最小值为:%d
",a,b,Query_min(a,b));  
57         printf("区间%d到%d的最大值和最小值只差为:%d
",a,b,Query_max(a,b)-Query_min(a,b));  
58     }  
59     return 0;  
60 } 
原文地址:https://www.cnblogs.com/lyqlyq/p/6880251.html