线段树练习_入门

  • 学习资源:nutonlysuccess
  • 基本规律:更新操作是点(更新点需要一直更新到树叶,所以复杂度较高,如果是线段更新那么就不能用基础的方法了),查询操作是区间

敌兵布阵

单点加值,查询区间和

const int MAXN = 51000;

#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

int tree[MAXN << 2];

void pushUP(int l, int r, int rt)
{
    tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}

void build(int l, int r, int rt)
{
    if (l == r)
    {
        RI(tree[rt]);
        return;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushUP(l, r, rt);
}

void update(int p, int add, int l, int r, int rt)
{
    if (l == r)
    {
        tree[rt] += add;
        return;
    }
    int m = (l + r) >> 1;
    if (p <= m)
        update(p, add, lson);
    else
        update(p, add, rson);
    pushUP(l, r, rt);
}

int query(int L, int R, int l, int r, int rt)
{
    if (L <= l && r <= R)
        return tree[rt];
    int ret = 0, m = (l + r) >> 1;
    if (L <= m)
        ret += query(L, R, lson);
    if (R > m)
        ret += query(L, R, rson);
    return ret;
}

int main()
{
//    freopen("in.txt", "r", stdin);
    int ncase, num, a, b;
    char type[10];
    RI(ncase);
    FE(kase, 1, ncase)
    {
        RI(num);
        build(1, num, 1);
        printf("Case %d:\n", kase);
        while (~RS(type) && type[0] != 'E')
        {
            RII(a, b);
            if (type[0] == 'Q')
            {
                printf("%d\n", query(a, b, 1, num, 1));
            }
            else if (type[0] == 'A')
            {
                update(a, b, 1, num, 1);
            }
            else if (type[0] == 'S')
            {
                update(a, -b, 1, num, 1);
            }
        }
    }
    return 0;
}

I Hate It

单点覆盖,查询区间最大值

const int MAXN = 210000;

#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1

int tree[MAXN << 2];

void pushUP(int l, int r, int rt)
{
    tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]);
}

void build(int l, int r, int rt)
{
    if (l == r)
    {
        RI(tree[rt]);
        return;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    pushUP(l, r, rt);
}

void update(int p, int v, int l, int r, int rt)
{
    if (l == r)
    {
        tree[rt] = v;
        return;
    }
    int m = (l + r) >> 1;
    if (p <= m)
        update(p, v, lson);
    else
        update(p, v, rson);
    pushUP(l, r, rt);
}

int query(int L, int R, int l, int r, int rt)
{
    if (L <= l && r <= R)
        return tree[rt];
    int ret = -INF, m = (l + r) >> 1;
    if (L <= m)
        ret = max(ret, query(L, R, lson));
    if (R > m)
        ret = max(ret, query(L, R, rson));
    return ret;
}

int main()
{
//    freopen("in.txt", "r", stdin);
    int ncase, num, a, b;
    char type;
    while (~RII(num, ncase))
    {
        build(1, num, 1);
        REP(i, ncase)
        {
            scanf(" %c %d %d", &type, &a, &b);
            if (type == 'Q')
            {
                printf("%d\n", query(a, b, 1, num, 1));
            }
            else
            {
                update(a, b, 1, num, 1);
            }
        }
    }
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值