HDU 1754

线段树的模板题。

buildTree, insert, update, query 四个函数写的时候注意叶子节点,左右孩子就行了


#include <stdio.h>
#include <string.h>

#define LEN 400400
#define NMAX -999999

typedef struct Node {
    int l, r;
    struct Node* lChild;
    struct Node* rChild;
    int nMax, id;
}Node;
Node tree[LEN];
int score[LEN];
int nCount;
int nMax;

void buildTree(Node* pRoot, int l, int r) {
    pRoot->l = l;
    pRoot->r = r;
    pRoot->nMax = NMAX;
    if(l != r) {
        nCount++;
        pRoot->lChild = tree + nCount;
        nCount++;
        pRoot->rChild = tree + nCount;
        buildTree(pRoot->lChild, l, (l+r)/2);
        buildTree(pRoot->rChild, (l+r)/2+1, r);
    }
}

void insert(Node* pRoot, int i, int num) {
    if(pRoot->l == i && pRoot->r == i) {
        pRoot->nMax = num;
        pRoot->id = i;
        return;
    }
    if(pRoot->nMax < num) {
        pRoot->nMax = num;
        pRoot->id = i;
    }
    int mid = (pRoot->l + pRoot->r)/2;
    if(i <= mid) {
        insert(pRoot->lChild, i, num);
    }
    else {
        insert(pRoot->rChild, i, num);
    }
}

void query(Node* pRoot, int s, int e) {
    if(pRoot->l == s && pRoot->r == e) {
        if(nMax < pRoot->nMax) {
            nMax = pRoot->nMax;
        }
        return;
    }
    int mid = (pRoot->l + pRoot->r)/2;
    if(e <= mid) {
        query(pRoot->lChild, s, e);
    }
    else if(s >= mid+1) {
        query(pRoot->rChild, s, e);
    }
    else {
        query(pRoot->lChild, s, mid);
        query(pRoot->rChild, mid+1, e);
    }
}

void update(Node* pRoot, int id, int num) {
    int i;
    if(pRoot->l == id && pRoot->r == id) {
        pRoot->nMax = num;
        return;
    }
    if(pRoot->id == id) {
        int tMax = NMAX;
        int index;
        for(i = pRoot->l; i <= pRoot->r; i++) {
            if(tMax < score[i]) {
                tMax = score[i];
                index = i;
            }
        }
        pRoot->nMax = tMax;
        pRoot->id = index;
        if(num > pRoot->nMax) {
            pRoot->nMax = num;
            pRoot->id = id;
        }
    }
    else if(num > pRoot->nMax) {
        pRoot->nMax = num;
        pRoot->id = id;
    }
    int mid = (pRoot->l + pRoot->r)/2;
    if(id <= mid) {
        update(pRoot->lChild, id, num);
    }
    else if(id >= mid+1) {
        update(pRoot->rChild, id, num);
    }
}

int main() {
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF) {
        int i, j, num;
        char cmd[10];
        nCount = 0;
        memset(tree, 0, sizeof(tree));
        memset(score, 0, sizeof(score));
        buildTree(tree, 1, n);
        for(i = 1; i <= n; i++) {
            scanf("%d", &num);
            score[i] = num;
            insert(tree, i, num);
        }
        for(i = 1; i <= m; i++) {
            int a, b;
            memset(cmd, 0, sizeof(cmd));
            scanf("%s%d%d", cmd, &a, &b);
            if('Q' == cmd[0]) {
                nMax = NMAX;
                query(tree, a, b);
                printf("%d\n", nMax);
            }
            else {
                score[a] = b;
                update(tree, a, b);
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值