POJ 3264 Balanced Lineup

POJ_3264

    这是一个RMQ问题,可以直接用线段树处理出区间的最大及最小值,在O(logN)的时间完成每次的查询操作。

#include<stdio.h>
#include<string.h>
#define MAXD 130000
#define INF 1000000000
int a[MAXD], b[MAXD], N, Q, M;
void init()
{
int i, j, k;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
for(M = 1; M < N + 2; M <<= 1);
for(i = 0, j = M + 1; i < N; i ++, j ++)
{
scanf("%d", &k);
a[j] = b[j] = k;
}
for(i = M - 1; i; i --)
{
a[i] = a[2 * i + 1];
if(a[i] == 0 || (a[2 * i] != 0 && a[2 * i] < a[i]))
a[i] = a[2 * i];
b[i] = b[2 * i + 1];
if(b[2 * i] > b[i])
b[i] = b[2 * i];
}
}
void solve()
{
int i, s, t, min, max;
for(i = 0; i < Q; i ++)
{
scanf("%d%d", &s, &t);
min = INF;
max = 0;
s = s - 1 + M;
t = t + 1 + M;
for(;s ^ t ^ 1; s >>= 1, t >>= 1)
{
if(~s & 1)
{
if(a[s ^ 1] && a[s ^ 1] < min)
min = a[s ^ 1];
if(b[s ^ 1] > max)
max = b[s ^ 1];
}
if(t & 1)
{
if(a[t ^ 1] && a[t ^ 1] < min)
min = a[t ^ 1];
if(b[t ^ 1] > max)
max = b[t ^ 1];
}
}
printf("%d\n", max - min);
}
}
int main()
{
while(scanf("%d%d", &N, &Q) == 2)
{
init();
solve();
}
return 0;
}


原文地址:https://www.cnblogs.com/staginner/p/2225927.html