</pre><p>问题描述:</p><p><span style="white-space:pre"> </span>相对比较简单的线段树的题。不用lazy也可解。只需要一个查询操作。不必增减。</p><p><span style="white-space:pre"> </span>在一串数中,找最大最小值的差。</p><p>解决办法:</p><p><span style="white-space:pre"> </span>细节:</p><p><span style="white-space:pre"> </span>1.<span style="white-space:pre">会因为cin cout超时,改成scanf printf就过了。</span></p><p><span style="white-space:pre"> </span>2.inf = 0xffffff0(32位整数)还有minV和maxV的初始化</p><p><span style="white-space:pre"> </span>过程:</p><p><span style="white-space:pre"> </span>终止条件:</p><p><span style="white-space:pre"> </span>Insert()里是遍历到叶子节点。</p><p><span style="white-space:pre"> </span>Query()里有俩。一是找不到比全局变量更小的最小值,更大的最大值。</p><p><span style="white-space:pre"> </span>二是查询范围恰好覆盖了树的左右结点</p><p>代码(参照课件里的写):</p><p><pre name="code" class="cpp">#include <iostream>
#include <cstdio>
using namespace std;
const int INF = 0xffffff0;
int minV = INF;
int maxV = -INF;
struct Node
{
int L, R;
int minV, maxV;
int Mid()
{
return (L + R)/2;
}
};
Node tree[800010];
void BuildTree(int root, int L, int R)
{
tree[root].minV = INF;//q1
tree[root].maxV = -INF;
tree[root].L = L;
tree[root].R = R;
if(L != R)
{
BuildTree(root * 2 + 1, L, tree[root].Mid());//q3 root是树的节点,LR是区间的长度
BuildTree(root * 2 + 2, tree[root].Mid() + 1, R);
}
}
void Insert(int root, int i, int v)
{//q4
if(tree[root].R == i && tree[root].L == i)
{
tree[root].minV = tree[root].maxV = v;
return;
}
tree[root].minV = min(tree[root].minV, v);//wa
tree[root].maxV = max(tree[root].maxV, v);
if(tree[root].Mid() >= i)
{
Insert(root * 2 + 1, i, v);
}
else
{
Insert(root * 2 + 2, i, v);
}
}
void Query(int root, int s, int e)
{//q2如何表示出两个终止节点
if(tree[root].minV >= minV && tree[root].maxV <= maxV)
{
return;
}
if(tree[root].L == s && tree[root].R == e)//&&?
{
minV = min(minV, tree[root].minV);
maxV = max(maxV, tree[root].maxV);
return;//
}
if(tree[root].Mid() >= e)//=
{
Query(root * 2 + 1, s, e);
}
else if(tree[root].Mid() < s)
{
Query(root * 2 + 2, s, e);
}
else
{
Query(root * 2 + 1, s, tree[root].Mid());
Query(root * 2 + 2, tree[root].Mid() + 1, e);//+1
}
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
BuildTree(0, 1, n);
for(int i = 1; i <= n; i++)//wa:0~n-1
{
int v;
scanf("%d", &v);
Insert(0, i, v);
}
for(int j = 0; j < m; j++)
{
int a, b;
scanf("%d%d", &a, &b);
minV = INF;
maxV = -INF;
Query(0, a, b);
printf("%d\n", maxV - minV);
}
return 0;
}