码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1754 线段树

时间:2015-06-23 21:24:18      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:

e,应该是线段树里的水题。线段树单点更新。查询区间最值。

代码套用模板 PS :模板有些地方不太懂。

#include<stdio.h>
#include<iostream>
#include<string.h>
#define maxn 200010
using namespace std;

int val[maxn];

struct Node
{
    int max;  // 需要求最值这里就改成最值
    int left, right;
}tree[maxn*4]; // 据说。线段树节点需要是数组的3~4倍大

int max(int a, int b)
{
    return a > b ? a : b;
}

int build(int root, int left, int right) // 以root为根节点 left 和 right 为数组长度的树
{
    tree[root].left = left;
    tree[root].right = right;
    if (left == right)
    return tree[root].max = val[left];  // 给叶子节点赋值

    int mid = (left + right) / 2;
    int a = build(2*root, left, mid);  // 建立左子树和右子树
    int b = build(2*root+1, mid+1, right);
    return tree[root].max = max(a, b);
}

int update(int root, int pos, int val) //单点更新 把pos 位置的元素更新为val
{
    if (tree[root].left == pos && tree[root].right == pos)    // 如果找到了该位置对应的节点
     return tree[root].max = val;
    if (tree[root].left > pos || tree[root].right < pos)    //如果不是。以上是两种递归突破口。e .但是我不太明白这两种情况返回值为什么是这样的。
     return tree[root].max;
    int a, b;
    a = update(2*root, pos, val);  // 更新左子树和右子树
    b = update(2*root+1, pos, val);
    return tree[root].max = max(a, b);
}

int calculate(int root, int left, int right) // 求取区间left 到 right中的最大值
{
    if (tree[root].left > right || tree[root].right < left)  // 如果当前区间和所求区间没有交集
      return 0;
    if (left <= tree[root].left && tree[root].right <= right)  // 如果当前区间完全包含在所求区间里。不明白为什么就要返回当前区间的最大值。
      return tree[root].max;
    int a, b;
    a = calculate(2*root, left, right);  // 上述两种情况都木有的话。需要分解所求区间,求子区间的最值。
    b = calculate(2*root+1, left, right);
    return max(a, b);
}

int main()
{
    int n, m;
    while(cin >> n >> m)
    {
        for (int i=1; i<=n; ++i)
         scanf("%d", &val[i]);
        build(1, 1, n);
        while(m--)
        {
            char temp;
            int a, b;
            cin >> temp >> a >> b;
            if (temp == ‘Q‘)
              cout << calculate(1, a, b) << endl;
            else update(1, a, b);
        }
    }
    return 0;
}




POJ 1754 线段树

标签:

原文地址:http://www.cnblogs.com/icode-girl/p/4596273.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!