最敏捷的机器人(线段树维护区间最值)
Posted nldqy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最敏捷的机器人(线段树维护区间最值)相关的知识,希望对你有一定的参考价值。
题面:
Wind设计了很多机器人。但是它们都认为自己是最强的,于是,一场比赛开始了……机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛。首先,他们面前会有一排共n个数,它们比赛看谁能最先把每连续k个数中最大和最小值写下来,当然,这些机器人运算速度都很,它们比赛的是谁写得快。但是Wind也想知道答案,你能帮助他吗?
Input:
每组测试数据
第1行为n,k(1<=k<=n<=100000)
第2行共n个数,为数字序列,所有数字均在int范围内。
Output:
共n-k+1行
第i行为第i~i+k-1这k个数中的最大和最小值
Sample Input:
5 3
1 2 3 4 5
Sample Output:
3 1
4 2
5 3
Solution:
线段树维护区间最大值和区间最小值,再暴力查询即可
要注意的是给出的数字可能为负数(在int范围内)
Code:
#include<bits/stdc++.h>
using namespace std;
int n,m,a[1000001];
struct sgt{
struct node{int minn,maxn;}tree[500001];
void build(int k,int l,int r){
if(l==r){
tree[k].minn=tree[k].maxn=a[l];
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);build(k<<1|1,mid+1,r);
tree[k].minn=min(tree[k<<1].minn,tree[k<<1|1].minn);
tree[k].maxn=max(tree[k<<1].maxn,tree[k<<1|1].maxn);
}
int query_min(int L,int R,int l,int r,int k){
if(l>R||r<L)return 2147483647;
if(l>=L&&r<=R)return tree[k].minn;
int re=2147483647;
int mid=(l+r)>>1;
re=min(query_min(L,R,l,mid,k<<1),query_min(L,R,mid+1,r,k<<1|1));
return re;
}
int query_max(int L,int R,int l,int r,int k){
if(l>R||r<L)return -2147483647;
if(l>=L&&r<=R)return tree[k].maxn;
int re=-2147483647;
int mid=(l+r)>>1;
re=max(query_max(L,R,l,mid,k<<1),query_max(L,R,mid+1,r,k<<1|1));
return re;
}
}T;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch==‘-‘)f=-f;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read();
T.build(1,1,n);
for(int i=1;i<=n-m+1;i++)
printf("%d %d
",T.query_max(i,i+m-1,1,n,1),T.query_min(i,i+m-1,1,n,1));
return 0;
}
以上是关于最敏捷的机器人(线段树维护区间最值)的主要内容,如果未能解决你的问题,请参考以下文章
[HDU5306] Gorgeous Sequence - 线段树区间最值操作
bzoj3064Tyvj 1518 CPU监控 线段树维护历史最值
hdu5306Gorgeous Sequence 线段树区间最值操作