結果

問題 No.3411 Range Clamp Sum
コンテスト
ユーザー AwashAmityOak
提出日時 2025-12-17 01:10:44
言語 C++23
(gcc 13.3.0 + boost 1.89.0)
結果
AC  
実行時間 4,470 ms / 10,000 ms
コード長 4,080 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 6,876 ms
コンパイル使用メモリ 337,760 KB
実行使用メモリ 13,184 KB
最終ジャッジ日時 2025-12-17 23:36:05
合計ジャッジ時間 61,427 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 28
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define all(x) x.begin(), x.end()

#define int long long
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int N, Q;
    cin >> N >> Q;
    assert(1 <= N && N <= 100000);
    assert(1 <= Q && Q <= 100000);
    
    vector<pair<int, int>> A(N);
    rep(i, N) {
        cin >> A[i].first;
        A[i].second = i;
        assert(0 <= A[i].first && A[i].first <= 100000);
    }
    
    int rN = (int)(sqrtl(N) + 0.5);
    int rQ = (int)(sqrtl(Q) + 0.5);
    
    vector<vector<tuple<int, int, int, int, int>>> queries((Q + rQ - 1) / rQ);
    rep(q, Q) {
        int t;
        cin >> t;
        assert(t == 1 || t == 2);
        
        if (t == 1) {
            int x, y;
            cin >> x >> y;
            assert(1 <= x && x <= N);
            assert(0 <= y && y <= 100000);
            --x;
            
            queries[q / rQ].emplace_back(t, x, y, -1, -1);
        } else {
            int l, r, a, b;
            cin >> l >> r >> a >> b;
            assert(1 <= l && l <= r && r <= N);
            assert(0 <= a && a <= b && b <= 100000);
            --l;
            
            queries[q / rQ].emplace_back(t, l, r, a, b);
        }
    }
    
    vector<int> ans(rQ);
    vector<int> sum0(N), sum1(N);
    vector<int> bsum0((N + rN - 1) / rN), bsum1((N + rN - 1) / rN);
    for (auto& block : queries) {
        fill(all(ans), 0LL);
        
        auto B = A;
        sort(all(B));
        vector<tuple<int, int, int, int, int>> events;
        events.reserve(block.size());
        rep(q, block.size()) {
            auto [t, l, r, a, b] = block[q];
            if (t == 1) continue;
            
            events.emplace_back(a, l, r, q, 0);
            events.emplace_back(b, l, r, q, 1);
        }
        sort(events.begin(), events.end());
        
        auto sum_query = [rN](vector<int>& block, vector<int>& sum, int l, int r) -> int {
            int res = 0;
            int bl = (l + rN - 1) / rN, br = r / rN;
            
            if (br < bl) {
                for (int i = l; i < r; ++i) res += sum[i];
            } else {
                for (int i = bl; i < br; ++i) res += block[i];
                for (int i = l; i < bl * rN; ++i) res += sum[i];
                for (int i = br * rN; i < r; ++i) res += sum[i];
            }
            return res;
        };
        
        int j = 0;
        fill(all(sum0), 0LL);
        fill(all(sum1), 0LL);
        fill(all(bsum0), 0LL);
        fill(all(bsum1), 0LL);
        for (auto [x, l, r, q, t] : events) {
            for (;j < N && B[j].first < x; ++j) {
                auto [a, i] = B[j];
                sum0[i] += 1;
                sum1[i] += a;
                bsum0[i / rN] += 1;
                bsum1[i / rN] += a;
            }
            
            if (t == 0) {
                ans[q] -= sum_query(bsum1, sum1, l, r);
                ans[q] += sum_query(bsum0, sum0, l, r) * x;
            } else {
                ans[q] += sum_query(bsum1, sum1, l, r);
                ans[q] += (r - l - sum_query(bsum0, sum0, l, r)) * x;
            }
        }
        
        unordered_map<int, int> update_history;
        rep(q, block.size()) {
            auto [t, l, r, a, b] = block[q];
            if (t == 1) {
                int x = l;
                int y = r;
                
                update_history[x] = y;
            } else {
                if (a > b) {
                    cout << a * (r - l) << '\n';
                    continue;
                }
                
                for (auto [i, x] : update_history) {
                    if (l <= i && i < r) {
                        ans[q] -= clamp(A[i].first, a, b);
                        ans[q] += clamp(x, a, b);
                    }
                }
                cout << ans[q] << '\n';
            }
        }
        
        for (auto [i, x] : update_history) {
            A[i].first = x;
        }
    }
}
0