Hello 2025_D. Gifts Order 线段树

传送门

容易想到同时维护ai+iaii,但是我一开始的做法是更新后再扫一遍才能更新出答案,这样不仅时间上爆炸,答案还更新不全。其实完全可以push_up的时候更新答案,这样不仅不会浪费复杂度,还不会漏情况

```cpp
#include<bits/stdc++.h>
    
using namespace std;
    
long long t;
const long long N = 2e5 + 10;
long long n,q,ans;
long long a[N];
struct node {
    long long pmax,pmin,nmax,nmin,ans1,ans2;
}tr[4 * N];

node up(node x,node y) {
    node res;
    res.pmax = max(x.pmax,y.pmax);
    res.pmin = min(x.pmin,y.pmin);
    res.nmax = max(x.nmax,y.nmax);
    res.nmin = min(x.nmin,y.nmin);
    res.ans1 = max({x.ans1,y.ans1,x.pmax - y.pmin});
    res.ans2 = max({x.ans2,y.ans2,y.nmax - x.nmin});
    return res;
}

void build(long long k,long long l,long long r) {
    if(l == r) {
        tr[k].pmax = tr[k].pmin = a[l] + l;
        tr[k].nmax = tr[k].nmin = a[l] - l;
        tr[k].ans1 = tr[k].ans2 = 0;
        return;
    }
    long long mid = (l + r) >> 1;
    build(k * 2,l,mid);
    build(k * 2 + 1,mid + 1,r);
    tr[k] = up(tr[k * 2],tr[k * 2 + 1]);
}

void change(long long k,long long l,long long r,long long x,long long v) {
    if(l > x || r < x) return;
    if(l == r && l == x) {
        tr[k].pmax = tr[k].pmin = v + l;
        tr[k].nmax = tr[k].nmin = v - l;
        return;
    }
    long long mid = (l + r) >> 1;
    change(k * 2,l,mid,x,v);
    change(k * 2 + 1,mid + 1,r,x,v);
    tr[k] = up(tr[k * 2],tr[k * 2 + 1]);
}

node query(long long k,long long l,long long r,long long x,long long y) {
    if(l > y || r < x) return (node){-1000000000,1000000000,-1000000000,1000000000,0,0};
    if(l >= x && r <= y) return tr[k];
    long long mid = (l + r) >> 1;
    node res;
    res = up(query(k * 2,l,mid,x,y),query(k * 2 + 1,mid + 1,r,x,y));
    return res;
}
    
void solve() {
    cin >> n >> q;
    for(long long i = 1;i <= n;i++) cin >> a[i];
    build(1,1,n);
    node tmp = query(1,1,n,1,n);
    cout << max(tmp.ans1,tmp.ans2) << '\n';
    for(long long p,x,i = 1;i <= q;i++) {
        cin >> p >> x;
        change(1,1,n,p,x);
        node tmp = query(1,1,n,1,n);
        cout << max(tmp.ans1,tmp.ans2) << '\n';
    }
}
    
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin >> t;
    while(t--) solve();
    
    return 0;
}
posted @   孤枕  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示
相见争如不见,多情何似无情。