您的位置:首页 > 其它

poj-2823 -- Sliding Window 区间最大值最小值 RMQ 与线段树

2012-08-24 19:23 429 查看
题意:一个有n个元素的数组num[],求所有num[i]~num[i+k]的最小值和最大值。

RMQ 算法小心空间,很容易被卡到

可以用线段树做,每个结点保存该线段的最大/小值...然后简单查询最大最小值即可

RMQ:

View Code

//Accepted    16596K    9204MS    C++    1487B
#include <stdio.h>
#include <string.h>
#define  inf 0x7fffffff
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 1000001;

int st_min[maxn<<2],st_max[maxn<<2];

inline int minn(int a,int b) { return a>b?b:a; }
inline int maxx(int a,int b) { return a>b?a:b; }
void PushUP(int rt)
{
st_min[rt] = minn(st_min[rt<<1],st_min[rt<<1|1]);
st_max[rt] = maxx(st_max[rt<<1],st_max[rt<<1|1]);
}
void build(int l,int r,int rt) {
if (l == r)
{
scanf("%d",&st_min[rt]);
st_max[rt] = st_min[rt];
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUP(rt);
}

int query_min(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R) {
return st_min[rt];
}
int m = (l + r) >> 1;
int ret1 = inf,ret2 = inf;
if (L <= m) ret1 = query_min(L , R , lson);
if (R > m) ret2 = query_min(L , R , rson);
return minn(ret1,ret2);
}
int query_max(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R) {
return st_max[rt];
}
int m = (l + r) >> 1;
int ret1 = -inf,ret2 = -inf;
if (L <= m) ret1 = query_max(L , R , lson);
if (R > m) ret2 = query_max(L , R , rson);
return maxx(ret1,ret2);
}

int main(void)
{
int n,m,i;
while(scanf("%d%d",&n,&m)!=EOF)
{
build(1 , n , 1);
for(i=1;i<=n-m+1;i++)
{
printf("%d ",query_min(i,i+m-1,1,n,1));
}
printf("\n");
for(i=1;i<=n-m+1;i++)
{
printf("%d ",query_max(i,i+m-1,1,n,1));
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: