結果

問題 No.877 Range ReLU Query
ユーザー toyamatoyama
提出日時 2019-09-06 23:19:32
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
MLE  
実行時間 -
コード長 2,713 bytes
コンパイル時間 1,335 ms
コンパイル使用メモリ 94,376 KB
実行使用メモリ 814,916 KB
最終ジャッジ日時 2023-09-07 02:35:03
合計ジャッジ時間 5,261 ms
ジャッジサーバーID
(参考情報)
judge12 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 MLE -
testcase_01 -- -
testcase_02 -- -
testcase_03 -- -
testcase_04 -- -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <functional>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
using namespace std;
template<class T, class Compare = less<T> >
using MaxHeap = priority_queue<T, vector<T>, Compare>;
template<class T, class Compare = greater<T> >
using MinHeap = priority_queue<T, vector<T>, Compare>;
using llong = long long;

llong n, q;
llong x;

vector<vector<llong> >seg;
vector<vector<llong> >sum;

void init(llong &n) {
    llong _n = 1;

    while (_n < n) _n *= 2;

    n = _n;
    seg.assign(2 * n, vector<llong>(1, 0));
    sum.assign(2 * n, vector<llong>(1, 0));
    for (int i = n - 2; i >= 0; i--) {
        seg[i].resize(seg[2 * i + 1].size() + seg[2 * i + 2].size());
        sum[i].assign(sum[2 * i + 1].size() + sum[2 * i + 2].size(), 0);
    }

    return;
};

void setv(llong k, llong v) {
    k += n - 1;
    seg[k][0] = v;
};

void build() {
    for (int i = n - 2; i >= 0; i--) {
        auto &l = seg[i * 2 + 1];
        auto &r = seg[i * 2 + 2];

        int l_i = 0;
        int r_i = 0;
        for (int j = 0; j < seg[i].size(); j++) {
            if (l_i >= l.size()) seg[i][j] = r[r_i++];
            if (r_i >= r.size()) seg[i][j] = l[l_i++];
            if (l[l_i] < r[r_i]) seg[i][j] = l[l_i++];
            else seg[i][j] = r[r_i++];
        }

        sum[i][0] = seg[i][0];
        for (int j = 1; j < sum[i].size(); j++) {
            sum[i][j] = sum[i][j - 1] + seg[i][j];
        }
    }
}

pair<llong, llong> acc(llong k, llong l, llong r) {
    llong idx = upper_bound(seg[k].begin(), seg[k].end(), x) - seg[k].begin();

    if (idx >= 1) {
        return make_pair(sum[k].back() - sum[k][idx - 1], sum[k].size() - idx);
    }
    else {
        return make_pair(sum[k].back(), sum[k].size());
    }
};

pair<llong, llong> query(llong l, llong r, llong k, llong a, llong b) {
    if (b < l || r < a) return make_pair(0, 0);

    if (l < a && b < r) {
        return acc(k, a, b);
    }
    else {
        pair<llong, llong> v1 = query(l, r, 2 * k + 1, a, (a + b) / 2);
        pair<llong, llong> v2 = query(l, r, 2 * k + 2, (a + b) / 2, b);

        return make_pair(v1.first + v2.first, v1.second + v2.second);
    }
};

int main() {
    cin >> n >> q;
    llong nn = n;

    init(n);
    for (int i = 0; i < nn; i++) {
        llong v;
        cin >> v;
        setv(i, v);
    }
    build();

    for (int i = 0; i < q; i++) {
        llong com, l, r, a;
        cin >> com >> l >> r >> a;
        x = a;

        pair<llong, llong> b = query(l, r, 0, 0, n);
        cout << b.first - (x * b.second) << endl;
    }

    return 0;
}
0