题目1544:数字序列区间最小值

题目描述:

给定一个数字序列,查询任意给定区间内数字的最小值。

 

输入:

输入包含多组测试用例,每组测试用例的开头为一个整数n(1<=n<=100000),代表数字序列的长度。
接下去一行给出n个数字,代表数字序列。数字在int范围内。
下一行为一个整数t(1<=t<=10000),代表查询的次数。
最后t行,每行给出一个查询,由两个整数表示l、r(1<=l<=r<=n)。

 

输出:

对于每个查询,输出区间[l,r]内的最小值。

 

样例输入:
5
3 2 1 4 3
3
1 3
2 4
4 5
样例输出:
1
1
3

 1 #include <stdio.h>
 2 #include <math.h>
 3  
 4  
 5 #define N 100001
 6  
 7 #define max(a,b) a>b?a:b
 8 #define min(a,b) a<b?a:b
 9  
10 int array[N];
11 int RMQ_min[N][20];
12 int RMQ_max[N][20];
13  
14  
15 void RMQ(int n)
16 {
17     int i;
18     int j;
19  
20     for(i = 1; i <= n; i++)
21     {
22         RMQ_min[i][0] = RMQ_max[i][0] = array[i];
23     }
24  
25     double limit = log((double)n)/log(2.0);
26  
27     for(j = 1 ; j <= (int)limit; j++)
28         for(i = 1; i + (1 << j) -1 <= n; i++)
29         {
30             RMQ_max[i][j] = max(RMQ_max[i][j-1], RMQ_max[i+(1<<(j-1))][j-1]);
31             RMQ_min[i][j] = min(RMQ_min[i][j-1], RMQ_min[i+(1<<(j-1))][j-1]);
32         }
33  
34 }
35  
36 int Max(int a, int b)
37 {
38     int k = (int)(log((double)(b-a+1))/log(2.0));
39     return max(RMQ_max[a][k],RMQ_max[b-(1<<k)+1][k]);
40 }
41  
42 int Min(int a, int b)
43 {
44     int k = (int)(log((double)(b-a+1))/log(2.0));
45     return min(RMQ_min[a][k],RMQ_min[b-(1<<k)+1][k]);
46 }
47  
48  
49 int main()
50 {
51  
52     int n;
53     int i;
54     int j;
55     int t;
56     int a;
57     int b;
58     int T[10001];
59     int TT;
60  
61     while(scanf("%d",&n) != EOF)
62     {   
63         for(i = 1 ; i <= n; i++)
64         {
65             scanf("%d",array+i);
66         }
67  
68         RMQ(n);
69  
70         j = 1;
71         scanf("%d",&t);
72         TT = t;
73  
74         while( t-- )
75         {
76             scanf("%d%d",&a, &b);
77             T[j++] = Min(a,b);
78         }
79  
80         for(i = 1 ;i <= TT; i++)
81         {
82             printf("%d
",*(T+i));
83         }
84     }
85  
86     return 0;
87 }
原文地址:https://www.cnblogs.com/chchche/p/3466023.html