poj3264 balanced

</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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值