题目链接:点击打开链接
题目大意:
给出一个数目为n的非有序序列,然后有m次查询.对于每次查询输入两个正整数l,r请输出区间[l,r]的最大值与最小值的差值
输入
第一行:输入两个正整数
n,m (1<=n<=50000, 1<=m<=200000 )
;
第二行:输入n个整数 大小范围为[1,100000];
接下来的m行,每次两个正整数l,r (1<=l<=r<=n);
输出
输出区间
[l,r]
最大值与最小值的差值
.
///思路:线段树的区间最值查找
#include <iostream>
35.#include<cstdio>
36.
37.using namespace std;
38.
39.void build(int node,int k,int e,int a[],int b[])
40.{
41. if(k==e)b[node]=a[k];
42. else
43. {
44. build(2*node,k,(k+e)/2,a,b);
45. build(2*node+1,(k+e)/2+1,e,a,b);
46. if(b[2*node]<=b[2*node+1])
47. b[node]=b[2*node];
48. else b[node]=b[node*2+1];
49. }
50.}
51.void build2(int node,int k,int e,int a[],int b[])
52.{
53. if(k==e)b[node]=a[k];
54. else
55. {
56. build2(2*node,k,(k+e)/2,a,b);
57. build2(2*node+1,(k+e)/2+1,e,a,b);
58. if(b[2*node]>=b[2*node+1])
59. b[node]=b[2*node];
60. else
61. b[node]=b[node*2+1];
62. }
63.}
64.int finde(int node,int k,int e,int a[],int b[],int l,int r)
65.{
66. int p1,p2;
67. if(l>e||r<k)return -1;
68. if(l<=k&&r>=e)return b[node];
69. p1=finde(2*node,k,(k+e)/2,a,b,l,r);
70. p2=finde(2*node+1,(k+e)/2+1,e,a,b,l,r);
71. if(p1==-1)return p2;
72. if(p2==-1)return p1;
73. if(p1<=p2)return p1;
74. return p2;
75.}
76.int finde2(int node,int k,int e,int a[],int b[],int l,int r)
77.{
78. int p1,p2;
79. if(l>e||r<k)return -1;
80. if(l<=k&&r>=e)return b[node];
81. p1=finde2(2*node,k,(k+e)/2,a,b,l,r);
82. p2=finde2(2*node+1,(k+e)/2+1,e,a,b,l,r);
83. if(p1==-1)return p2;
84. if(p2==-1)return p1;
85. if(p1<=p2)return p2;
86. return p1;
87.}
88.int main()
89.{
90. int a[50000];
91. int b[200100];
92. int c[200100];
93. int n,m;
94. scanf("%d%d",&n,&m);
95. for(int i=1; i<=n; i++)
96. {
97. scanf("%d",&a[i]);
98. }
99. build(1,1,n,a,b);
100. build2(1,1,n,a,c);
101. int l,r;
102. for(int i=0; i<m; i++)
103. {
104. scanf("%d%d",&l,&r);
105. int mi=finde(1,1,n,a,b,l,r);
106. int mx=finde2(1,1,n,a,c,l,r);
107. printf("%d\n",mx-mi);
108.
109. }
110. return 0;
111.}
112.