POJ 3264 Balanced Lineup【RMQ附模板】
2014-07-24 17:46
513 查看
题目:http://poj.org/problem?id=3264
输入n和m组,接着n个数,然后是每组的区间下标范围,求这个区间内的最大与最小的差
参考好多:
http://blog.sina.com.cn/s/blog_9ec86af101013o84.html http://www.cnblogs.com/whatbeg/p/3582486.html http://www.myext.cn/other/a_7364.html http://baike.baidu.com/view/1536346.htm
RMQ 1813MS
O(nlogn)预处理 O(1)应答
dp[i][j]表示从i号元素开始2^j个元素间的最值
dp[i][j-1] 表示[i,i+2^(j-1)-1]
dp[i+(1<<(j-1))][j-1] 表示[i+2^(j-1),i+2^j-1]
ST算法:
线段树:
ST模板
输入n和m组,接着n个数,然后是每组的区间下标范围,求这个区间内的最大与最小的差
参考好多:
http://blog.sina.com.cn/s/blog_9ec86af101013o84.html http://www.cnblogs.com/whatbeg/p/3582486.html http://www.myext.cn/other/a_7364.html http://baike.baidu.com/view/1536346.htm
RMQ 1813MS
O(nlogn)预处理 O(1)应答
dp[i][j]表示从i号元素开始2^j个元素间的最值
dp[i][j-1] 表示[i,i+2^(j-1)-1]
dp[i+(1<<(j-1))][j-1] 表示[i+2^(j-1),i+2^j-1]
ST算法:
#include<iostream> #include<cmath> using namespace std; #define max_(a,b) ((a)>(b)?(a):(b)) #define min_(a,b) ((a)>(b)?(b):(a)) int h[51005]; int maxdp[51001][20],mindp[51001][20]; int n,m; void Init() { int i,j,t; for(i=1;i<=n;i++) { maxdp[i][0] = h[i]; mindp[i][0] = h[i]; } for(j=1; (1<<j) <=n; j++) { for(i=1; i+(1<<j)-1<=n; i++) { t = i + (1 << (j-1)); //注意+比<<优先级高 maxdp[i][j] = max_(maxdp[i][j-1],maxdp[t][j-1]); mindp[i][j] = min_(mindp[i][j-1],mindp[t][j-1]); } } } int rmq(int l,int r) { int k,mx,my; k=(int)(log(r-l+1.0)/log(2.0)); mx = max_(maxdp[l][k],maxdp[r-(1<<k)+1][k]); my = min_(mindp[l][k],mindp[r-(1<<k)+1][k]); return mx-my; } int main() { int l,r,i; // freopen("a.txt","r",stdin); int rmp(int l,int r); while(~scanf("%d%d",&n,&m)) { for( i=1;i<=n;i++) scanf("%d",&h[i]); Init(); for( i=0;i<m;i++) { scanf("%d%d",&l,&r); printf("%d\n",rmq(l,r)); } } return 0; }
线段树:
#include <cstdio> #include <cmath> #include <cstring> #include <set> #include <stack> #include <queue> #include <vector> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define INF 0x7FFFFFFF #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define CLR( a , x ) memset ( a , x , sizeof (a) ) #define RE freopen("1.in","r",stdin) #define WE freopen("1.out","w",stdout) #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)>(b)?(b):(a)) #define MAX 50001 int ans1,ans2; //整体的最大最小 int a[MAX]; struct node { int l,r; //i结点的区间范围 int nMax,nMin; //[l,r]的最值 }tree[MAX*4]; void build(int i,int l,int r) //在结点i处建立[l,r]的区间 { tree[i].l = l; tree[i].r = r; if(l == r) //叶结点 { tree[i].nMax = tree[i].nMin = a[l]; return; } int mid = (l+r)>>1; build(i<<1,l,mid); build(i<<1|1,mid+1,r); tree[i].nMax = max(tree[i<<1].nMax,tree[i<<1|1].nMax); tree[i].nMin = min(tree[i<<1].nMin,tree[i<<1|1].nMin); } void query(int i,int l,int r) //在i号结点查询[l,r] { if(tree[i].l == l && tree[i].r == r) //完全覆盖了 { ans1 = max(tree[i].nMax,ans1); ans2 = min(tree[i].nMin,ans2); return; } int mid = (tree[i].l+tree[i].r)>>1; if(r <= mid) //被查询的区间被含于i结点左区间,就去左子树找该区间 query(i<<1,l,r); else if(l > mid) //右子树找该区间 query(i<<1|1,l,r); else // l<=mid && r>mid [l,r各在一边],[l,mid]在做左子树找 { query(i<<1,l,mid); query(i<<1|1,mid+1,r); } } int main() { int n,m,l,r; // RE; while(scanf("%d%d",&n,&m)!=EOF) { for(int i = 1; i <= n;i++) scanf("%d",&a[i]); build(1,1,n); REP(i,m) { scanf("%d%d",&l,&r); ans1 = -INF; ans2 = INF; query(1,l,r); printf("%d\n",ans1-ans2); } } return 0; }
ST模板
#include <stdio.h> #include <math.h> #define MIN 30 #define MAX 50050 int n,m,arr[MAX]; int maxdp[MAX][MIN],mindp[MAX][MIN]; int RMQ(int x,int y,int flag); int max_m(int a,int b) { return a>b?a:b; } int min_m(int a,int b) { return a>b?b:a; } void Create(int flag) { //flag = 0建立最大rmq,flag = 1最小 int i,j,t; if (flag == 0) { for (i = 1; i <= n; ++i) maxdp[i][0] = arr[i]; for (j = 1; (1<<j) <= n; ++j) for (i = 1; i+(1<<j)-1 <= n; ++i) { t = i + ( 1 << (j-1) ); maxdp[i][j] = max_m(maxdp[i][j-1],maxdp[t][j-1]); } } else { for (i = 1; i <= n; ++i) mindp[i][0] = arr[i]; for (j = 1; (1<<j) <= n; ++j) for (i = 1; i+(1<<j)-1 <= n; ++i) { t = i + ( 1 << (j-1) ); mindp[i][j] = min_m(mindp[i][j-1],mindp[t][j-1]); } } } int RMQ(int l,int r,int flag) { //flag = 0查询最大rmq,flag = 1最小 int k = (int)(log(r-l+1.0)/log(2.0)); if (flag == 0) return max_m(maxdp[l][k],maxdp[r-(1<<k)+1][k]); else return min_m(mindp[l][k],mindp[r-(1<<k)+1][k]); } int main() { int i,j,k; scanf("%d%d",&n,&m); for (i = 1; i <= n; ++i) scanf("%d",&arr[i]); Create(1); Create(0); for (i = 1; i <= m; ++i) { scanf("%d%d",&j,&k); printf("%d\n",RMQ(j,k,0) - RMQ(j,k,1)); } } /* //若数组从0开始,其他不变 void Init(){ int i,j,t; for (i = 0; i < n; ++i) mindp[i][0] =h[ i]; for (j = 1; (1<<j) <= n; ++j){ for (i = 0; i+(1<<j)-1 < n; ++i){ t = i + ( 1 << (j-1) ); mindp[i][j] = min_m(mindp[i][j-1],mindp[t][j-1]); } } } */
相关文章推荐
- POJ 3264 Balanced Lineup 【RMQ求区间最值模板题】
- poj 3264 Balanced Lineup【RMQ-ST查询区间最大最小值之差 +模板应用】
- poj 3264 Balanced Lineup--RMQ问题模板题
- POJ 3264 Balanced Lineup 【RMQ求区间最值模板题】
- POJ 3264 Balanced Lineup(RMQ模板)
- POJ 3264 Balanced Lineup【RMQ模板题】
- poj 3264 Balanced Lineup (RMQ算法 模板题)
- POJ-3264 Balanced Lineup(rmq模板题)
- POJ 3264 Balanced Lineup (区间最值 RMQ模板/线段树)
- (模板题)poj 3264 Balanced Lineup(RMQ的ST算法)
- [POJ] - 3264 Balanced Lineup [RMQ][ST]
- POJ 3264 Balanced Lineup (RMQ)
- POJ - 3264 - Balanced Lineup(RMQ)
- POJ3264 Balanced Lineup (RMQ & ST)
- poj 3264 Balanced Lineup (线段树模板题)
- [POJ 3264]Balanced Lineup(ST算法求RMQ)
- POJ-3264 Balanced Lineup【RMQ】
- POJ 3264 Balanced Lineup(RMQ)
- POJ 3264 Balanced Lineup(RMQ)
- poj 3264 Balanced Lineup(RMQ裸题)