poj3264
来源:互联网 发布:mysql 创建触发器 编辑:程序博客网 时间:2024/05/01 01:22
Description
For the daily milking, Farmer John's N cows(1 ≤ N ≤ 50,000) always line up in the same order. One dayFarmer John decides to organize a game of Ultimate Frisbee with some of thecows. To keep things simple, he will take a contiguous range of cows from themilking lineup to play the game. However, for all the cows to have fun theyshould 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 todetermine the difference in height between the shortest and the tallest cow inthe group.
Input
Line 1: Two space-separated integers, N and Q.
Lines 2..N+1: Line i+1 contains a single integer that is theheight of cow i
Lines N+2..N+Q+1: Two integers A and B (1≤ A ≤ B ≤ N), representing therange of cows from A to B inclusive.
Output
Lines 1..Q: Each line contains a single integerthat is a response to a reply and indicates the difference in height betweenthe tallest and shortest cow in the range.
题目大意为:
任意输入一组数字(A1,A2, A3 ……Ai), 求任意区间(Ai……Aj)中的最大数和最小数的差(Max(Ai)- Min(Aj))。
这是一个很基础的线段树题目
代码如下:
#include<iostream>
using namespace std ;
const int INF = 99999999 ;
int min = INF ;
int max = -INF ;
struct Node
{
int L, R ;
int s_min, s_max ;
};
Node tree[800000] ;
void BuildTree(int root, int L, int R) ;
void Insert(int root, int i, int v) ;
void Query(int root, int s, int e) ;
int Max(int a, int b) ;
int Min(int a, int b) ;
int main()
{
int a, b, sign ;
int i;
scanf("%d %d", &a, &b) ;
BuildTree(0, 1, a) ;
for(i = 1; i <= a; i++ )
{
scanf("%d", &sign) ;
Insert(0, i, sign) ;
}
for(i = 0; i < b; i++ )
{
int s, e;
scanf("%d %d", &s, &e) ;
min = INF ;
max = -INF ;
Query(0, s, e) ;
printf("%d\n", max - min) ;
}
return 0 ;
}
void BuildTree(int root, int L, int R)
{
tree[root].L = L ;
tree[root].R = R ;
tree[root].s_min = INF ;
tree[root].s_max = -INF ;
if(L != R)
{
BuildTree(2*root+1, L, (L+R)/2) ;
BuildTree(2*root+2, (L+R)/2+1, R) ;
}
}
void Insert(int root, int i, int v)
{
if(tree[root].L == tree[root].R)
{
tree[root].s_min = tree[root].s_max = v ;
return ;
}
tree[root].s_min = Min(tree[root].s_min, v) ;
tree[root].s_max = Max(tree[root].s_max, v) ;
if(i <= (tree[root].L+tree[root].R)/2)
{
Insert(2*root + 1, i, v) ;
}
else
{
Insert(2*root + 2, i, v) ;
}
}
void Query(int root, int s, int e)
{
if(tree[root].s_min >= min && tree[root].s_max <=max)
return ;
if(tree[root].L == s && tree[root].R == e)
{
min = Min(min, tree[root].s_min) ;
max = Max(max, tree[root].s_max) ;
return ;
}
if(e <= (tree[root].L+tree[root].R)/2)
Query(2*root + 1, s, e) ;
else if(s > (tree[root].L+tree[root].R)/2)
Query(2*root + 2, s, e) ;
else
{
Query(2*root+1, s, (tree[root].L+tree[root].R)/2) ;
Query(2*root+2, (tree[root].L+tree[root].R)/2+1, e);
}
}
int Max(int a, int b)
{
if(a >= b)
return a ;
else
return b ;
}
int Min(int a, int b)
{
if(a <= b)
return a ;
else
return b ;
}
主要代码为以下三个函数:
void BuildTree(int root, int L, int R) ,voidInsert(int root, int i, int v) ,voidQuery(int root, int s, int e) 。 Build()是建立一个线段树, Insert()是把每输入一个数后,就将这个数插入到已经建立好的线段树中,插入的位置以这个数是第几次输入的为索引。Query()就是解决任意区间中最大数和最小数的查询函数了。
解决题目之前,需要思考,树的的每个结点中放些什么,结点中必须要有的有:区间起点L,和区间终点R([L,R])。每个结点表示一个区间, 题目要求是:求出任意区间中最大数和最小数的差,所以,每个结点Node中还需要存max和min,于是Node结点就定义出来了:
struct Node
{
int L, R ;
int s_min, s_max ;
};
Build()和Insert()为线段树必须要有的两个模板函数。
Query()用来查询,如何查询? 每个结点代表一个区间,那么我们就判断输入的区间是否和树中某个结点的L和R相等,相等就将结点中的max和min取出来,否就继续啊向下查询。
- poj3264
- poj3264
- poj3264
- poj3264
- POJ3264
- POJ3264
- POJ3264
- poj3264
- POJ3264
- poj3264
- poj3264
- poj3264
- poj3264
- POJ3264
- poj3264
- poj3264
- poj3264
- poj3264
- JAVA设计模式之策略模式
- 南邮-2047(地铁换线)
- anagrams两种解法 用map来优化查找
- 实验二
- Js各种继承方法总结
- poj3264
- quick-cocos2d-x3.2 scheduler使用注意事项
- 领会
- 主页导航设计
- Fedora20 kermit串口工具
- C语言上机
- 考试冲刺期--软件设计师
- java中枚举类型enum的使用和分析
- 使用sort命令和awk命令对数据集的label进行处理