POJ 3264 Balanced Lineup -- RMQ或线段树

时间:2022-09-16 06:25:16

一段区间的最值问题,用线段树或RMQ皆可。两种代码都贴上:又是空间换时间。。

RMQ 解法:(8168KB 1625ms)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define N 50003 int a[N],dmin[N][],dmax[N][],n; void RMQ_init()
{
int i,j;
for(i=;i<=n;i++)
dmin[i][] = dmax[i][] = a[i];
for(j=;(<<j)<=n;j++)
{
for(i=;i+(<<j)-<=n;i++)
{
dmin[i][j] = min(dmin[i][j-],dmin[i+(<<(j-))][j-]);
dmax[i][j] = max(dmax[i][j-],dmax[i+(<<(j-))][j-]);
}
}
} int RMQ(int l,int r)
{
int k = ;
while((<<(k+)) <= r-l+)
k++;
return max(dmax[l][k],dmax[r-(<<k)+][k]) - min(dmin[l][k],dmin[r-(<<k)+][k]);
} int main()
{
int q,i;
while(scanf("%d%d",&n,&q)!=EOF)
{
for(i=;i<=n;i++)
scanf("%d",&a[i]);
RMQ_init();
while(q--)
{
int l,r;
scanf("%d%d",&l,&r);
if(l>r)
swap(l,r);
printf("%d\n",RMQ(l,r));
}
}
return ;
}

线段树解法:(1172KB  2297ms)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define N 50003 struct node
{
int maxi,mini;
}tree[*N]; void pushup(int rt)
{
tree[rt].maxi = max(tree[*rt].maxi,tree[*rt+].maxi);
tree[rt].mini = min(tree[*rt].mini,tree[*rt+].mini);
} void build(int l,int r,int rt)
{
if(l == r)
{
scanf("%d",&tree[rt].maxi);
tree[rt].mini = tree[rt].maxi;
return;
}
int mid = (l+r)/;
build(l,mid,*rt);
build(mid+,r,*rt+);
pushup(rt);
} int query_max(int l,int r,int aa,int bb,int rt)
{
if(aa>r || bb<l)
return -;
if(aa<=l && bb>=r)
return tree[rt].maxi;
int mid = (l+r)/;
return max(query_max(l,mid,aa,bb,*rt),query_max(mid+,r,aa,bb,*rt+));
} int query_min(int l,int r,int aa,int bb,int rt)
{
if(aa>r || bb<l)
return ;
if(aa<=l && bb>=r)
return tree[rt].mini;
int mid = (l+r)/;
return min(query_min(l,mid,aa,bb,*rt),query_min(mid+,r,aa,bb,*rt+));
} int main()
{
int n,q,i;
while(scanf("%d%d",&n,&q)!=EOF)
{
build(,n,);
for(i=;i<=q;i++)
{
int l,r;
scanf("%d%d",&l,&r);
if(l>r)
swap(l,r);
printf("%d\n",query_max(,n,l,r,)-query_min(,n,l,r,));
}
}
return ;
}