2022fjut校赛题解-I题

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);
    }
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值