언어 :
균형 잡힌 라인업
시간 제한 : 5000MS 메모리 제한 : 65536k 나
총 제출 : 64,465 허용 : 30,048
케이스 시간 제한 : 2000MS
설명
매일 착유를 들어, 농부 존의 N 소 (1 ≤ N ≤ 50,000)은 항상 같은 순서로 정렬. 어느 날 농부 요한은 젖소의 일부 궁극적 인 프리스비의 게임을 구성하기로 결정합니다. 일을 간단하게 유지하기 위해, 그는 게임을 착유 라인업에서 젖소의 연속 범위를 취할 것입니다. 모든 소는 재미를위한 그러나, 그들은 높이가 너무 많은 차이가 있습니다.
농부 존 Q 목록 (1 ≤ Q ≤ 200,000) 소의 잠재적 인 그룹과 높이 (1 개 ≤ 높이 ≤ 100)을 만들었다. 각 그룹에 대해, 그는 짧고 그룹에서 가장 높은 소 사이의 높이 차이를 결정하기 위해 당신의 도움을 원한다.
입력
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
分析,题目要求求指定区间的最大最下值的差值,用到区间树就会更加简单,先构建树再输入数值时候可以对每个区间的最大最小值进行操作。
首先定义每个节点,必须要包括左右边界,向上取整中间值,其余需要存储的数据根据题目要求添加
구조체 데이터 / / 노드
{
INT R & LT, L;
INT MID () // 중간 반올림 값
{
창 (R & LT + L) / 2;
}
}
각 구간의 제목 필요한 최소 및 최대 값은 각각의 섹션에 추가되어야
struct data
{
int R,L;
int max,min;
int mid()
{
return (R+L)/2;
}
}
두 번째 단계는 범위 트리를 구축하는 것입니다
Build(int root,int R,int L)
{
对数值进行操作
if (r != l)
{
build(2*root+1,l,(r+l)/2);
build(2 * root + 2, ((r + l) / 2) + 1, r);
}
}
세 번째 단계 삽입
void insert(int root,int i,int v)
{
if (p[root].l == p[root].r)
{
数值操作
return;
}
数值操作
if (p[root].mid() >= i)
insert(2 * root + 1, i, v);
else
insert(2 * root + 2, i, v);
}
주제 코드
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF = 0xffffff0;//负无穷
int maxv = -INF;
int minv = INF;
struct d
{
int r, l;
int max, min;
int mid()
{
return (l+r)/2;
}
}p[800010];
void build(int root, int l, int r)
{
p[root].l = l;
p[root].r = r;
p[root].max = -INF;
p[root].min = INF;
if (r != l)
{
build(2*root+1,l,(r+l)/2);
build(2 * root + 2, ((r + l) / 2) + 1, r);
}
}
void insert(int root,int i,int v)
{
if (p[root].l == p[root].r)
{
p[root].max = p[root].min = v;
return;
}
p[root].max = max(v, p[root].max);
p[root].min = min(v, p[root].min);
if (p[root].mid() >= i)
insert(2 * root + 1, i, v);
else
insert(2 * root + 2, i, v);
}
void find(int root,int l,int r)
{
if (p[root].max <= maxv && p[root].min >= minv) //剪枝
return;
if (p[root].l == l&&p[root].r == r)//如果找到正好重合的区间就停止向下找
{
maxv = max(maxv, p[root].max);
minv = min(minv,p[root].min);
return;
}
if (p[root].mid() >= r)
find(2 * root + 1, l, r);
else if (p[root].mid() < l)
find(2 * root + 2, l, r);
else
{
find(2 * root + 1, l, p[root].mid());
find(2 * root + 2, p[root].mid() + 1, r);
}
}
int main()
{
int n, t, m;
int R, L;
scanf("%d%d",&n,&t);
build(0, 1, n);
for (int i = 1; i <= n; i++)
{
scanf("%d",&m);
insert(0,i,m);
}
for (int i = 1; i <= t; i++)
{
scanf("%d%d",&L,&R);
minv = INF;
maxv = -INF;
find(0,L,R);
printf("%d\n",maxv-minv);
}
return 0;
}