結果

問題 No.877 Range ReLU Query
ユーザー m_tsubasam_tsubasa
提出日時 2019-09-30 15:09:44
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 661 ms / 2,000 ms
コード長 2,525 bytes
コンパイル時間 2,245 ms
コンパイル使用メモリ 179,128 KB
実行使用メモリ 65,512 KB
最終ジャッジ日時 2024-04-25 22:16:48
合計ジャッジ時間 9,408 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,812 KB
testcase_01 AC 4 ms
6,944 KB
testcase_02 AC 3 ms
6,940 KB
testcase_03 AC 5 ms
6,940 KB
testcase_04 AC 2 ms
6,944 KB
testcase_05 AC 3 ms
6,944 KB
testcase_06 AC 3 ms
6,940 KB
testcase_07 AC 3 ms
6,944 KB
testcase_08 AC 5 ms
6,940 KB
testcase_09 AC 3 ms
6,940 KB
testcase_10 AC 3 ms
6,940 KB
testcase_11 AC 619 ms
57,212 KB
testcase_12 AC 546 ms
56,296 KB
testcase_13 AC 425 ms
38,688 KB
testcase_14 AC 442 ms
35,920 KB
testcase_15 AC 661 ms
64,636 KB
testcase_16 AC 640 ms
64,084 KB
testcase_17 AC 657 ms
65,076 KB
testcase_18 AC 643 ms
64,604 KB
testcase_19 AC 440 ms
65,512 KB
testcase_20 AC 576 ms
65,436 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

// 1-indexed
template <class T>
struct SegmentTree {
  // a,b,c: T, e:T(unit)
  // abc = (ab)c = a(bc)
  // ae = ea = a
  typedef function<T(T &, T &)> F;
  int n;
  F f;
  T unit;
  function<long long(T &, long long)> g;
  vector<T> dat;
  SegmentTree(){};
  SegmentTree(int newn, F f, T t,
              function<long long(T &, long long)> g)
      : f(f), unit(t), g(g) {
    init(newn);
  }
  void init(int newn) {
    n = 1;
    while(n < newn) n <<= 1;
    dat.assign(n << 1, unit);
  }
  void build(vector<T> &v) {
    for(int i = 0; i < v.size(); ++i) dat[i + n] = v[i];
    for(int i = n - 1; i > 0; --i)
      dat[i] = f(dat[(i << 1)], dat[(i << 1) | 1]);
  }

  // "go up" process
  void update(int k, T newdata) {
    dat[k += n] = newdata;
    while(k >>= 1) {
      dat[k] = f(dat[(k << 1) | 0], dat[(k << 1) | 1]);
    }
  }
  // [a,b)
  long long query(int a, int b, long long x) {
    long long ans = 0;
    for(int l = a + n, r = b + n; l < r; l >>= 1, r >>= 1) {
      if(l & 1) ans += g(dat[l++], x);
      if(r & 1) ans += g(dat[--r], x);
    }
    return ans;
  }
};

long long n, q;
struct data {
  vector<long long> v, sum;
};
data dummy;
vector<data> v;

int main() {
  auto f = [](data &l, data &r) {
    data newd;
    int lid = 0, rid = 0, lsize = l.v.size(),
        rsize = r.v.size();
    // merge sort
    while(lid < lsize || rid < rsize) {
      if(lid < lsize && rid < rsize) {
        if(l.v[lid] < r.v[rid])
          newd.v.push_back(l.v[lid++]);
        else
          newd.v.push_back(r.v[rid++]);
      }
      else if(lid < lsize)
        newd.v.push_back(l.v[lid++]);
      else
        newd.v.push_back(r.v[rid++]);
    }
    newd.sum.assign(newd.v.size() + 1, 0);
    for(int i = 0; i < newd.v.size(); ++i)
      newd.sum[i + 1] = newd.sum[i] + newd.v[i];
    return newd;
  };
  auto g = [](data &d, long long x) {
    long long ans = *(d.sum.end() - 1);
    int id = upper_bound(d.v.begin(), d.v.end(), x) -
             d.v.begin();
    ans -= d.sum[id];
    return ans - x * ((int)d.v.size() - id);
  };
  dummy.sum.push_back(0);
  cin >> n >> q;
  SegmentTree<data> seg(n, f, dummy, g);
  for(int i = 0; i < n; ++i) {
    data now;
    long long a;
    cin >> a;
    now.v.push_back(a);
    now.sum.push_back(0);
    now.sum.push_back(a);
    v.push_back(now);
  }
  seg.build(v);
  for(int i = 0; i < q; ++i) {
    long long c, l, r, x;
    cin >> c >> l >> r >> x;
    cout << seg.query(l - 1, r, x) << endl;
  }
  return 0;
}
0