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 }