您的位置:首页 > 其它

POJ P3264 USACO 2007 洛谷 P2880 January Silver Balanced Lineup【线段树】

2018-02-11 10:32 477 查看
题目索引:http://poj.org/problem?id=3264
Balanced Lineup
Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 58842 Accepted: 27537
Case Time Limit: 2000MS
DescriptionFor 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.
InputLine 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.OutputLines 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 Input6 3
1
7
3
4
2
5
1 5
4 6
2 2Sample Output6
3
0SourceUSACO 2007 January Silver

题目大意:有N个数以及M个询问,每次询问(L,R)求数列区间L~R的最大值与最小值的差。
题目读懂了这道题就好做了。首先暴力很容易想到,但是肯定要超时;事实上这种题应该有很多种做法,线段树不难想到。
由于这道题过于简单,我们只需要建一棵维护区间max与min的线段树即可(事实上没有修改不存在维护)。
代码如下:#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio>
#define _M 100000+5
#define Inf 1e9
using namespace std;
struct Node{
int A,B,Max,Min;
};
Node Tree[4*_M];
int N,Q;
int Num[_M];
int Read(){
bool F=0;int X=0;char CH=getchar();
while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
while(CH>='0'&&CH<='9'){X=(X<<3)+(X<<1)+CH-'0';CH=getchar();}
return F?-X:X;
}
void Write(int X){
if(X<0)X=-X,putchar('-');
if(X>9)Write(X/10);
putchar(X%10+48);
}
void MakeTree(int P,int X,int Y){//建树
Tree[P].A=X;
Tree[P].B=Y;
if(X<Y){
MakeTree(P<<1,X,X+Y>>1);
MakeTree(P<<1|1,(X+Y>>1)+1,Y);
Tree[P].Max=max(Tree[P<<1].Max,Tree[P<<1|1].Max);
Tree[P].Min=min(Tree[P<<1].Min,Tree[P<<1|1].Min);
}
else Tree[P].Max=Tree[P].Min=Num[X];
}
int GetMax(int P,int X,int Y){//求区间最大值
if(X<=Tree[P].A&&Tree[P].B<=Y){
return Tree[P].Max;
}
int LMax=0;
int RMax=0;
if(X<=Tree[P].A+Tree[P].B>>1&&Y>=Tree[P].A){
LMax=GetMax(P<<1,X,Y);
}
if(Y>Tree[P].A+Tree[P].B>>1&&X<=Tree[P].B){
RMax=GetMax(P<<1|1,X,Y);
}
return max(LMax,RMax);
}
int GetMin(int P,int X,int Y){//求区间最小值
if(X<=Tree[P].A&&Tree[P].B<=Y){
return Tree[P].Min;
}
int LMin=Inf;
int RMin=Inf;
if(X<=(Tree[P].A+Tree[P].B)>>1&&Y>=Tree[P].A){
LMin=GetMin(P<<1,X,Y);
}
if(Y>Tree[P].A+Tree[P].B>>1&&X<=Tree[P].B){
RMin=GetMin(P<<1|1,X,Y);
}
return min(LMin,RMin);
}
int main(){
int I,J,K;
for(N=Read(),Q=Read(),I=1;I<=N;I++){
Num[I]=Read();
}MakeTree(1,1,N);
for(I=1;I<=Q;I++){
int Start=Read(),End=Read();
Write(GetMax(1,Start,End)-GetMin(1,Start,End));
putchar('\n');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: