Problem
思路
这题就是离散化,加权值线段树板子(树状数组),就是离散化的时候要把所有可能出现的值预处理出来,所以还需要离线处理一波,思路简单可以直接套板子。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll a[N], b[N];
ll tr[2 * N], num[2 * N];
ll eecnt, cnt;
int lowbit(int x) {return x & -x;}
struct ee{ll op, id, sa;}v[N];
int f(ll x){return lower_bound(num + 1, num + cnt + 1, x) - num;}
int main() {
int n, t;cin >> n >> t; num[0] = -1e18;
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
for (int i = 1; i <= n; i++) b[i] = a[i], num[++cnt] = a[i];
for (int i = 1; i <= t; i++) {
ll op; scanf("%lld", &op);
if(op != 3) {
ll id, sa; scanf("%lld%lld", &id, &sa);
v[++eecnt] = {op, id, sa};
if(op == 1) b[id] += sa, num[++cnt] = b[id];
else b[id] = max(b[id] - sa, 0LL), num[++cnt] = b[id];
} else {
ll sa; scanf("%lld", &sa);
v[++eecnt] = {op, -1, sa};
}
}
sort(num + 1, num + 1 + cnt);
for (int i = 1; i <= n; i++) {
int x = f(a[i]);
for (int j = x; j <= cnt; j += lowbit(j))
tr[j]++;
}
for (int i = 1; i <= t; i++) {
ll op = v[i].op, id= v[i].id, sa = v[i].sa, x;
if(op == 1) {
x = f(a[id]);
for (int j = x; j <= cnt;j += lowbit(j))
tr[j]--;
a[id] += sa;
x = f(a[id]);
for (int j = x; j <= cnt; j += lowbit(j))
tr[j]++;
} else if(op == 2) {
x = f(a[id]);
for (int j = x; j <= cnt; j += lowbit(j))
tr[j]--;
a[id] = max(a[id] - sa, 0LL);
x = f(a[id]);
for (int j = x; j <= cnt; j += lowbit(j))
tr[j]++;
} else {
ll sum = 0, res = 0; x = f(sa);
for (int j = x - 1; j; j -= lowbit(j)) sum += tr[j];
x = f(num[cnt]);
for (int j = x; j; j -= lowbit(j)) res += tr[j];
printf("%lld\n", res - sum);
}
}
}