一眼 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 longusing 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