【题解】AT_abc432_e [ABC432E] Clamp

一眼 ds 题。

分析一下第二个式子:
\(l\leq r\),此时对于每个 \(a_i\),其贡献 \(sum\) 一定在 \([l,r]\) 中。具体地:

\[sum= \begin{cases} l,\ a_i < l \\ a_i,\ l\leq a_i\leq r \\ r,\ a_i>r \\ \end{cases}\]

对于第一、三种情况,考虑使用 BIT 维护数字的出现次数。
第二种情况也很好想:再用一个 BIT 维护数字之和。

修改操作就先撤销一个数的贡献,再加上新数的贡献。

诶到这里你可能会发现不对。
是的,因为题目并没有说明 \(l\leq r\)!!

于是思考 \(l>r\) 的情况:
就当你想与其大战一番的时候,你惊讶地发现它的答案就是 \(n\times l\)
(因为无论怎样,\(\min(r,a_i)\) 都一定 \(\leq r\),而 \(r<l\),所以最大值恒为 \(l\)

然后这道题就做完了。

注意:BIT 的 update(x,del)\(x\) 可能为 \(0\)

Code

// no note
#include<bits/stdc++.h>

typedef int IT;
typedef long long LL;
typedef __int128 int128;
typedef double DB;
typedef long double LDB;

#define pb push_back
#define fst first
#define sec second
#define psh push
#define mkp make_pair
#define PII pair<IT,IT>
#define PLI pair<LL,IT>
#define lowbit(x) ((x)&(-x))

#define int long long

using namespace std;

const int N=5e5+10,V=5e5,DEL=2;

int n,q;
int a[N];

struct BIT{
    int t[V+12];

    void update(int x,int del){
        for(;x<=V+DEL;x+=lowbit(x)) t[x]+=del;
        return;
    }
    int query(int x){
        int res=0;
        for(;x;x-=lowbit(x)) res+=t[x];
        return res;
    }
}T1,T2;
// 个数,和

signed main(){
    scanf("%lld %lld",&n,&q);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]),T1.update(a[i]+DEL,1),T2.update(a[i]+DEL,a[i]);

    for(int i=1;i<=q;i++){
        int opt,x,y;
        scanf("%lld %lld %lld",&opt,&x,&y);
        if(opt&1){
            T1.update(a[x]+DEL,-1);
            T2.update(a[x]+DEL,-a[x]);
            a[x]=y;
            T1.update(a[x]+DEL,1);
            T2.update(a[x]+DEL,a[x]);
        }
        else{
            if(x>y){
                LL res=1ll*n*x;
                printf("%lld\n",res);
                continue;
            }
            LL res=1ll*(T1.query(x-1+DEL)-T1.query(-1+DEL))*x+1ll*(T1.query(V+DEL)-T1.query(y+DEL))*y+(T2.query(y+DEL)-T2.query(x-1+DEL));
            printf("%lld\n",res);
        }
    }
    return 0;
}

link

posted @ 2025-11-16 22:24  YuYuanPQ  阅读(3)  评论(0)    收藏  举报