提出 #72382755


ソースコード 拡げる

#include <iostream>
#include <vector>
#include <functional>
#define fastio cin.tie(0)->sync_with_stdio(0)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define compress(v) sort(all(v)), v.erase(unique(all(v)), v.end())
#define sz(x) (int)(x).size()
using namespace std;

template<typename Node>
struct SegTree {
    int n, lg, size;
    Node e; // 항등원
    vector<Node> tree;
    function<Node(Node, Node)> func;
    int log2(int n) {
        int res = 0;
        while (n > (1 << res)) res++;
        return res;
    }
    SegTree(int n, const Node& e, auto func) : n(n), lg(log2(n)), size(1<<lg), e(e), tree(size<<1, e), func(func) {}
    SegTree(const vector<Node>& v, const Node& e, auto func) : n(sz(v)), lg(log2(n)), size(1<<lg), e(e), tree(size<<1, e), func(func) {
        for (int i = 0; i < n; i++) {
            tree[i+size] = v[i];
        }
        for (int i = size-1; i > 0; i--) {
            tree[i] = func(tree[i<<1], tree[i<<1 | 1]);
        }
    }
    void add(int i, const Node& val) {
        tree[--i |= size] += val;
        while (i >>= 1) {
            tree[i] = func(tree[i<<1], tree[i<<1 | 1]);
        }
    }
    void update(int i, const Node& val) {
        tree[--i |= size] = val;
        while (i >>= 1) {
            tree[i] = func(tree[i<<1], tree[i<<1 | 1]);
        }
    }
    Node query(int i) {
        return tree[--i | size];
    }
    Node query(int l, int r) {
        Node L = e, R = e;
        for (--l |= size, --r |= size; l <= r; l >>= 1, r >>= 1) {
            if (l & 1) L = func(L, tree[l++]);
            if (~r & 1) R = func(tree[r--], R);
        }
        return func(L, R);
    }
    int find_kth(Node k) {
        int node = 1, st = 1, en = size;
        while (st != en) {
            int mid = (st + en) / 2;
            node <<= 1;
            if (tree[node] >= k) {
                en = mid;
            }
            else {
                k -= tree[node];
                node |= 1; st = mid+1;
            }
        }
        return st;
    }
};
typedef long long ll;
struct Node {
    int cnt, cnt2; ll sum;
    Node operator+(const Node& o) const {
        return { cnt + o.cnt, cnt2 + o.cnt2, sum + o.sum };
    }
    Node& operator+=(const Node& o) {
        cnt += o.cnt; cnt2 += o.cnt2;
        sum += o.sum; return *this;
    }
    bool operator>=(const Node& o) const {
        return cnt >= o.cnt;
    }
    Node& operator-=(const Node& o) {
        cnt -= o.cnt; return *this;
    }
};
const int MAX = 1e6;
int main() {
    fastio; int N, Q; cin >> N >> Q;
    SegTree<Node> sg(MAX, { 0, 0, 0 }, [](Node a, Node b) { return a + b; });
    ll sum2 = 0; int cnt2 = 0;
    vector<pair<ll,ll>> v(N);
    auto update = [&](ll a, int b, int ty) {
        int c2 = 0;
        if (b == 2) {
            cnt2 += ty; c2 = ty;
        }
        sum2 += ty * a;
        sg.add(a, { ty, c2, ty * a });
    };
    for (auto& [a, b] : v) {
        cin >> a >> b;
        update(a, b, 1);
    }
    auto calc = [&]() {
        int t = min(N-1, cnt2);
        if (t <= 0) {
            cout << sum2 << "\n"; return;
        }
        int idx = sg.find_kth({ sg.tree[1].cnt - t + 1, 0, 0 });
        auto up = sg.query(idx+1, MAX);
        int k = t - up.cnt;
        ll ans = sum2 + up.sum + (ll)k*idx;
        int c2 = up.cnt2;
        auto tmp = sg.query(idx);
        int b2 = max(0, k - tmp.cnt + tmp.cnt2);
        if (c2 + b2 == t && cnt2 == t) {
            ans -= idx;
            if (N > t) {
                int nxt = sg.find_kth({ sg.tree[1].cnt - t, 0, 0 });
                ans += nxt;
            }
        }
        cout << ans << "\n";
    };
    for (int q = 0; q < Q; q++) {
        int w, x, y; cin >> w >> x >> y;
        auto& [a, b] = v[w-1];
        update(a, b, -1);
        a = x; b = y;
        update(x, y, 1);
        calc();
    }
    return 0;
}

提出情報

提出日時
問題 F - Egoism
ユーザ Lov34ever
言語 C++23 (GCC 15.2.0)
得点 550
コード長 4005 Byte
結果 AC
実行時間 339 ms
メモリ 39296 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 550 / 550
結果
AC × 2
AC × 22
セット名 テストケース
Sample 00-sample-01.txt, 00-sample-02.txt
All 00-sample-01.txt, 00-sample-02.txt, 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt, 01-09.txt, 01-10.txt, 01-11.txt, 01-12.txt, 01-13.txt, 01-14.txt, 01-15.txt, 01-16.txt, 01-17.txt, 01-18.txt, 01-19.txt, 01-20.txt
ケース名 結果 実行時間 メモリ
00-sample-01.txt AC 15 ms 36056 KiB
00-sample-02.txt AC 15 ms 35992 KiB
01-01.txt AC 102 ms 36068 KiB
01-02.txt AC 82 ms 36236 KiB
01-03.txt AC 87 ms 36120 KiB
01-04.txt AC 164 ms 35996 KiB
01-05.txt AC 92 ms 36108 KiB
01-06.txt AC 208 ms 38744 KiB
01-07.txt AC 339 ms 39296 KiB
01-08.txt AC 196 ms 38100 KiB
01-09.txt AC 164 ms 38732 KiB
01-10.txt AC 132 ms 38116 KiB
01-11.txt AC 193 ms 39124 KiB
01-12.txt AC 290 ms 39264 KiB
01-13.txt AC 306 ms 39272 KiB
01-14.txt AC 325 ms 39192 KiB
01-15.txt AC 122 ms 37160 KiB
01-16.txt AC 182 ms 39012 KiB
01-17.txt AC 138 ms 39012 KiB
01-18.txt AC 166 ms 38412 KiB
01-19.txt AC 255 ms 38504 KiB
01-20.txt AC 174 ms 37644 KiB