莫队 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\n",a,b,Query_max(a,b)); 56 printf("区间%d到%d的最小值为:%d\n",a,b,Query_min(a,b)); 57 printf("区间%d到%d的最大值和最小值只差为:%d\n",a,b,Query_max(a,b)-Query_min(a,b)); 58 } 59 return 0; 60 }