Balanced Lineup(POJ-3264)

Description

For the daily milking, Farmer John’s N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.

Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.

Input

Line 1: Two space-separated integers, N and Q.
Lines 2..N+1: Line i+1 contains a single integer that is the height of cow i
Lines N+2..N+Q+1: Two integers A and B (1 ≤ A ≤ B ≤ N), representing the range of cows from A to B inclusive.

Output

Lines 1..Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.

Sample Input

6 3
1
7
3
4
2
5
1 5
4 6
2 2

Sample Output

6
3
0

Source

USACO 2007 January Silver

这几天在学线段树入门,数据结构这一块确实感觉比较难……花了一两天才稍微有点领悟,之前写了几道模版题也没什么收获,权当背模版了。这应该是第一道从头到尾自己写的线段树的题目(建树那里稍微卡了一下)。

思路:

首先一开始照模版写了num数组储存原数值用来建树,后来发现不行。那就换做每次建树到叶节点的时候进行输入。
刚开始用了两个query查找区间最大最小值然后tle了,于是换成了一个,在区间范围内每次遇到叶节点就比较并更新最大值和最小值。
又t了,把cin/cout换成了scanf/printf,AC了,时间1610ms。

#include <iostream>
#include <cstdlib>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <list>
#include <algorithm>
#define MST(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int MAXN = 50000 + 100;
const int INF = 0x3f3f3f3f;
int n, q, tmp, tmp_min, tmp_max;
struct tree {
    int left, right, maxx, minn;
} T[MAXN * 3];
void build(int x, int l, int r) {
    T[x].left = l;
    T[x].right = r;
    if (l == r) {
        scanf("%d", &tmp);
        T[x].maxx = T[x].minn = tmp;
        return ;
    }
    int m = (l + r) >> 1;
    build(x << 1, l, m);
    build(x << 1 | 1, m + 1, r);
    T[x].maxx = max(T[x << 1].maxx, T[x << 1 | 1].maxx);
    T[x].minn = min(T[x << 1].minn, T[x << 1 | 1].minn);
//    printf("%d: %d %d %d %d\n", x, T[x].left, T[x].right, T[x].maxx, T[x].minn);
}
void query(int x, int l, int r) {
    if (T[x].left > r || T[x].right < l) return ;
    if (T[x].left == l && T[x].right == r) {
        tmp_max = max(tmp_max, T[x].maxx);
        tmp_min = min(tmp_min, T[x].minn);
        return ;
    }
    int m = (T[x].left + T[x].right) >> 1;
    if (m < l) query(x << 1 | 1, l, r);
    else if (m >= r) query(x << 1, l, r);
    else {
        query(x << 1, l, m);
        query(x << 1 | 1, m + 1, r);
    }
}
int main() {
    while (scanf("%d %d", &n, &q) != EOF) {
        MST(T, 0);
        build(1, 1, n);
        while (q--) {
            int x, y;
            scanf("%d %d", &x, &y);
            tmp_min = INF;
            tmp_max = -INF;
            query(1, x, y);
            printf("%d\n", tmp_max - tmp_min);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/white_yasha/article/details/80444484