hdu1754 线段树

什么都不说了,贴代码,理解的时候画个树来理解理解就好了,这个也是典型的牺牲空间复杂度来缩短时间复杂度的典型算法。。。。大哭

还是附点图上来吧。。。。。鼠标画的,见谅

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define maxn 200005
using namespace std;

int a[maxn * 4];

void build(int left, int right, int root)
{
    if(left == right)
        scanf("%d", &a[root]);
    else
    {
        int mid = (left + right) / 2;
        build(left, mid, root * 2);
        build(mid + 1, right, root * 2 + 1);
        a[root] = max(a[root * 2], a[root * 2 + 1]);
    }
}

void up(int x, int y, int left, int right, int root)
{
    if(left == right)
        a[root] = y;
    else
    {
        int mid = (left + right) / 2;
        if(x <= mid)
            up(x, y, left, mid, root * 2);
        else
            up(x, y, mid + 1, right, root * 2 + 1);
        a[root] = max(a[root * 2], a[root * 2 + 1]);
    }
}

int query(int x, int y, int left, int right, int root)
{
    if(x <= left && y >= right)
        return a[root];
    else
    {
        int sum = 0;
        int mid = (left + right) / 2;
        if(x <= mid)
            sum = max(sum, query(x, y, left, mid, root * 2));
        if(y > mid)
            sum = max(sum, query(x, y, mid + 1, right, root * 2 + 1));
        return sum;
    }
}

int main()
{
    int m, n;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        build(1, n, 1);

        int x, y;
        char c;
        for(int i = 1; i <= 10; i ++)
            cout << a[i] << endl;
        getchar();
        while(m --)
        {
            scanf("%c %d %d", &c, &x, &y);
//            cout << c << ' ' << x << ' ' << y << endl;
            getchar();
            if(c == 'Q')
                cout << query(x, y, 1, n, 1) << endl;
            else
                up(x, y, 1, n, 1);
        }
        memset(a, 0, sizeof(a));
    }
    return 0;
}


posted @ 2014-07-16 16:42  MrYu4  阅读(16)  评论(0编辑  收藏  举报