POJ 3264 线段树模板题

之前做的那道是区间求和的,这道题是求区间最大值和最小值之差的,感觉这道题更简单。只需在插入时把每个区间的最大值最小值求出来保存在根节点上就可以啦~\(^o^)/

Balanced Lineup

Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 39475   Accepted: 18524
Case Time Limit: 2000MS

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

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdio>
 5 using namespace std;
 6 #define INF 0x7fffffff
 7 int minv=INF,maxv=-INF;
 8 struct node
 9 {
10     int l,r;
11     int minv,maxv;
12     int mid()
13     {
14         return (l+r)/2;
15     }
16 }tree[8000010];
17 void buildtree(int root,int l,int r)
18 {
19     tree[root].l=l;
20     tree[root].r=r;
21     tree[root].minv=INF;
22     tree[root].maxv=-INF;
23     if(l!=r)
24     {
25         buildtree(root*2+1,l,(l+r)/2);
26         buildtree(root*2+2,(l+r)/2+1,r);
27     }
28 }
29 void insert(int root,int i,int v)
30 {
31     if(tree[root].l==tree[root].r)
32     {
33         tree[root].r=i;
34         tree[root].minv=tree[root].maxv=v;
35         return;
36     }
37     tree[root].minv=min(tree[root].minv,v);
38     tree[root].maxv=max(tree[root].maxv,v);
39     if(i<=tree[root].mid())
40         insert(2*root+1,i,v);
41     else
42         insert(2*root+2,i,v);
43 }
44 void query(int root,int s,int e)
45 {
46     if(tree[root].minv>minv&&tree[root].maxv<maxv)
47         return;
48     if(tree[root].l==s&&tree[root].r==e)
49     {
50         minv=min(minv,tree[root].minv);
51         maxv=max(maxv,tree[root].maxv);
52         return;
53     }
54     if(e<=tree[root].mid())
55         query(2*root+1,s,e);
56     else if(s>tree[root].mid())
57         query(2*root+2,s,e);
58     else
59     {
60         query(2*root+1,s,tree[root].mid());
61         query(2*root+2,tree[root].mid()+1,e);
62     }
63 }
64 int main()
65 {
66     int n,q,h;
67     int i,j,k;
68     scanf("%d%d",&n,&q);
69     buildtree(0,1,n);
70     for(i=1;i<=n;i++)
71     {
72         scanf("%d",&h);
73         insert(0,i,h);
74     }
75     for(i=0;i<q;i++)
76     {
77         int s,e;
78         scanf("%d%d",&s,&e);
79         minv=INF;
80         maxv=-INF;
81         query(0,s,e);
82         printf("%d\n",maxv-minv);
83     }
84     return 0;
85 }

时间: 2024-11-06 22:44:33

POJ 3264 线段树模板题的相关文章

[POJ2104] 区间第k大数 [区间第k大数,可持久化线段树模板题]

可持久化线段树模板题. #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <vector> using namespace std; int n,q,tot,a[110000]; in

LA 2191电位计(线段树模板题)

线段树模板题,没啥好说的.....注意输出是case之间空一行就行.........之前一直没注意,一直wa 代码如下: #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #includ

1270. 数列区间最大值(climits用法+线段树模板题)

题目链接: https://www.acwing.com/problem/content/1272/ 题解: 线段树模板题,单点求和.区间查询都可 AC代码: #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <climits> using namespace std; const int N = 1e5+10; int a

POJ 3468 线段树裸题

这些天一直在看线段树,因为临近期末,所以看得断断续续,弄得有些知识点没能理解得很透切,但我也知道不能钻牛角尖,所以配合着刷题来加深理解. 然后,这是线段树裸题,而且是最简单的区间增加与查询,我参考了ACdreamer的模板,在此基础上自己用宏定义来精简了一下代码: 1 #include<cstdio> 2 typedef long long LL; 3 #define root int rt, int l, int r 4 #define lson rt*2, l, mid 5 #define

poj 3264 线段树

线段树太弱了,题目逼格一高连代码都读不懂,今天开始重刷线段树,每天一题,风格用kuangbin大神和以前的,两种都写一遍 RMQ做法:poj3264 1 /* 2 POJ 3264 Balanced Lineup 3 题目意思:给定Q(1<=Q<=200000)个数A1,A2,```,AQ, 4 多次求任一区间Ai-Aj中最大数和最小数的差 5 */ 6 #include<stdio.h> 7 #include<algorithm> 8 #include<iost

POJ&mdash;&mdash;3264线段树

题目: 输入两个数(m,n),m表示牛的头数,n表示查询的个数.查询时输入两个数(x,y),表示查询范围的起始值和终止值,查询结果是,这个区间内牛重量的最大值减去牛重量的最小值,数量级为1000,000 设计每次查询的复杂度为logm. 例如, 输入: 6 3 1 7 3 4 2 5 1 5 4 6 2 2 输出: 6 3 0     分析:这道题是典型的空间换时间的题.一看到是区间的查找,我们应该想到线段树,这里有一篇我觉得写得挺好的介绍线段树的博客和大家分享一下:http://www.cnb

P1243~P1247 线段树模板题总结

前言 这几天刚刚刷了5道线段树(水)题,现在来总结一下. 首先是犯的不少错误: 1.建树.更新函数没有return.这是最气的,每次最后程序错误查了半天也没查出来,最后发现是没有return.递归边界要return,递归边界要return,递归边界要return,重要的事情说三遍. 2.判断查找区间于线段的变量写反.听说这个是常犯错误. 然后说一下学线段树的收获.线段树的代码量的确多,很能练自己的思维,而且学的过程中简单的理解了一下#define的用处.线段树用来解决区间查询,区间修改都很方便,

HDU 1166 线段树模板题

坐了3天的火车,终于到外婆家了(┬_┬).这次北京之旅颇有感触,虽然学到的东西不是很多(主要是自己的原因,没有认真学,并不是老师讲的不好),不过出去见见世面也是好的.最后一场比赛印象颇深,被虐的有点惨....记得当时有道题感觉自己能过,想用数组模拟链表水过,可是无论怎么优化一直超时@[email protected]后面比完后听朋友说那题应该用线段树做,顿时恍然大悟,然并卵,线段树的模板早忘了.....今天做道线段树的模板题先复习一下,过会再想想那道题. 敌兵布阵 Time Limit: 200

poj2823 线段树模板题 点修改(也可以用单调队列)

这道题吧 没计算时间 因为给了那么多 一算还可以 就直接写了线段树,刘汝佳那本模板 然后!poj的g++比C++慢大约500ms.......g++tle,C++就过了 Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 67576   Accepted: 19163 Case Time Limit: 5000MS Description An array of size n ≤ 106 is