AcWing 245. 你能回答這些問題嗎(單點修改+區間查詢)

題目鏈接:點擊這裏

在這裏插入圖片描述
在這裏插入圖片描述

query裏的pushup不是合併樹中的節點,只是借用一下pushup這個函數來算一下答案。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
const int N = 500010;

int w[N];

struct Node
{
    int l, r;       // 區間左右端點
    int tmax;       // 最大連續子段和
    int lmax;       // 最大前綴和
    int rmax;       // 最大後綴和
    int sum;        // 區間和
}tr[N * 4];

inline int lc(int p) { return p << 1; }
inline int rc(int p) { return p << 1 | 1; }

void pushup(Node &u, Node &l, Node &r)
{
    u.sum = l.sum + r.sum;
    u.lmax = max(l.lmax, l.sum + r.lmax);
    u.rmax = max(r.rmax, r.sum + l.rmax);
    u.tmax = max(max(l.tmax, r.tmax), l.rmax + r.lmax);
}

void build(int u, int l, int r)
{
    tr[u].l = l, tr[u].r = r;
    if(l == r)  { tr[u] = {l, r, w[l], w[l], w[l], w[l]}; return; }
    
    int mid = l + r >> 1;
    build(lc(u), l, mid);
    build(rc(u), mid + 1, r);
    
    pushup(tr[u], tr[lc(u)], tr[rc(u)]);
}

void modify(int u, int x, int v)
{
    if(tr[u].l == x && tr[u].r == x)    { tr[u] = {x, x, v, v, v, v}; return; }
    
    int mid = tr[u].l + tr[u].r >> 1;
    if(x <= mid)    modify(lc(u), x, v);
    else    modify(rc(u), x, v);
    
    pushup(tr[u], tr[lc(u)], tr[rc(u)]);
}

Node query(int u, int l, int r)
{
    if(l <= tr[u].l && r >= tr[u].r)    return tr[u];   // 樹節點被當前區間完全包含
    
    int mid = tr[u].l + tr[u].r >> 1;
    
    if(r <= mid)    return query(lc(u), l, r);         // 當前區間全在樹節點的左側
    else if(l > mid)    return query(rc(u), l, r);     // 當前區間全在樹節點的右側
    else                                               // 當前區間在樹節點的左右兩邊
    {
        auto left = query(lc(u), l, r);
        auto right = query(rc(u), l, r);
        Node res;
        pushup(res, left, right);
        return res;
    }
}

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &w[i]);
    
    build(1, 1, n);
    
    while(m--)
    {
        int k, x, y;
        scanf("%d%d%d", &k, &x, &y);
        if(k == 1)
        {
            if(x > y)   swap(x, y);
            printf("%d\n", query(1, x, y).tmax);
        }
        else
        {
            modify(1, x, y);
        }
    }

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章