poj 3264 Balanced Lineup (RMQ算法 模板题)

RMQ支持操作: 

Query(L, R):  计算Min{a[L],a[L+1], a[R]}。

预处理时间是O(nlogn), 查询只需 O(1)。

 

RMQ问题 用于求给定区间内的最大值/最小值问题。。询问的次数多的时候 好用。。

 

这个题目我至少得开数组开到 80000才能过,不知道为什么。。刚开始还写错了,贡献了好多RE和WA..

题目:http://poj.org/problem?id=3264

题意:给n个数,q次询问,求最值的差。。

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 const int maxn = 80000;
 5 const int maxm = 30;
 6 int d_min[maxn][maxm],d_max[maxn][maxm],a[maxn];
 7 int n;
 8 
 9 void RMQ_init()
10 {
11     int i,j;
12     for(i = 1; i <= n; i++)
13     {
14         d_min[i][0] = a[i];
15         d_max[i][0] = a[i];
16     }
17     for(j = 1; (1<<j) <= n; j++)
18     for(i = 1; i + j - 1 <= n; i++)
19     {
20         d_min[i][j] = min(d_min[i][j-1],d_min[i + (1<<(j-1))][j-1]);
21         d_max[i][j] = max(d_max[i][j-1],d_max[i + (1<<(j-1))][j-1]);
22     }
23 }
24 
25 int RMQ_min(int l,int r)
26 {
27     int k = 0;
28     while((1<<(k+1)) <= r-l+1)
29     k++;
30     return min(d_min[l][k], d_min[r-(1<<k)+1][k]);
31 }
32 int RMQ_max(int l,int r)
33 {
34     int k = 0;
35     while((1<<(k+1)) <= r-l+1)
36     k++;
37     return max(d_max[l][k], d_max[r-(1<<k)+1][k]);
38 }
39 int main()
40 {
41     int q,l,r,i;
42     scanf("%d%d",&n,&q);
43     for(i = 1; i <= n; i++)
44     scanf("%d",&a[i]);
45     RMQ_init();
46 
47     while(q--)
48     {
49         scanf("%d%d",&l,&r);
50         printf("%d\n",RMQ_max(l,r)-RMQ_min(l,r));
51     }
52     return 0;
53 }

 

我的模板:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 using namespace std;
 7 const int maxn = 100000;
 8 const int maxm = 30;
 9 int d_min[maxn][maxm],d_max[maxn][maxm],a[maxn];
10 int n;
11 
12 void RMQ_init()
13 {
14     int i,j;
15     for(i = 1; i <= n; i++)  //数组下标从1开始的。
16     {
17         d_min[i][0] = a[i];
18         d_max[i][0] = a[i];
19     }
20     for(j = 1; (1<<j) <= n; j++)
21     for(i = 1; i + j - 1 <= n; i++)
22     {
23         d_min[i][j] = min(d_min[i][j-1],d_min[i + (1<<(j-1))][j-1]);
24         d_max[i][j] = max(d_max[i][j-1],d_max[i + (1<<(j-1))][j-1]);
25     }
26 }
27 
28 int RMQ_min(int l,int r)
29 {
30     int k = 0;
31     while((1<<(k+1)) <= r-l+1)
32     k++;
33     return min(d_min[l][k], d_min[r-(1<<k)+1][k]);
34 }
35 int RMQ_max(int l,int r)
36 {
37     int k = 0;
38     while((1<<(k+1)) <= r-l+1)
39     k++;
40     return max(d_max[l][k], d_max[r-(1<<k)+1][k]);
41 }
42 int main()
43 {
44     int i,l,r;
45     cin>>n;
46     for(i = 1; i <= n; i++)  //数组下标从1开始的。
47     cin>>a[i];
48     RMQ_init();
49     while(cin>>l>>r)
50     {
51         cout<<RMQ_min(l,r)<<endl;
52         cout<<RMQ_max(l,r)<<endl;
53     }
54     return 0;
55 }

 

posted @ 2014-02-16 20:09  水门  阅读(1382)  评论(1编辑  收藏  举报