結果

問題 No.649 ここでちょっとQK!
ユーザー CoCo_Japan_panCoCo_Japan_pan
提出日時 2023-02-04 00:45:21
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 79 ms / 3,000 ms
コード長 3,172 bytes
コンパイル時間 1,967 ms
コンパイル使用メモリ 174,840 KB
実行使用メモリ 10,044 KB
最終ジャッジ日時 2023-09-15 21:08:11
合計ジャッジ時間 5,163 ms
ジャッジサーバーID
(参考情報)
judge11 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 3 ms
4,616 KB
testcase_01 AC 3 ms
4,692 KB
testcase_02 AC 3 ms
4,632 KB
testcase_03 AC 29 ms
6,272 KB
testcase_04 AC 62 ms
10,044 KB
testcase_05 AC 64 ms
9,420 KB
testcase_06 AC 68 ms
9,536 KB
testcase_07 AC 3 ms
4,684 KB
testcase_08 AC 3 ms
4,568 KB
testcase_09 AC 3 ms
4,684 KB
testcase_10 AC 3 ms
4,684 KB
testcase_11 AC 3 ms
4,668 KB
testcase_12 AC 41 ms
6,976 KB
testcase_13 AC 42 ms
7,040 KB
testcase_14 AC 40 ms
6,956 KB
testcase_15 AC 41 ms
7,080 KB
testcase_16 AC 40 ms
7,036 KB
testcase_17 AC 43 ms
7,104 KB
testcase_18 AC 47 ms
7,336 KB
testcase_19 AC 51 ms
7,540 KB
testcase_20 AC 55 ms
7,740 KB
testcase_21 AC 60 ms
8,944 KB
testcase_22 AC 64 ms
9,072 KB
testcase_23 AC 68 ms
10,024 KB
testcase_24 AC 71 ms
9,100 KB
testcase_25 AC 76 ms
9,036 KB
testcase_26 AC 79 ms
9,736 KB
testcase_27 AC 3 ms
4,680 KB
testcase_28 AC 3 ms
4,688 KB
testcase_29 AC 3 ms
4,568 KB
testcase_30 AC 33 ms
7,024 KB
testcase_31 AC 31 ms
6,908 KB
testcase_32 AC 3 ms
4,568 KB
testcase_33 AC 3 ms
4,692 KB
testcase_34 AC 3 ms
4,568 KB
testcase_35 AC 3 ms
4,676 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
#define ALL(x) (x).begin(), (x).end()
using ll = long long;

template <typename T>
// 内部では1-baseですが、外からは0-baseに見せてます
struct fenwickTree {
   public:
    fenwickTree(int size) : _size(size), data(size + 1, 0) {
        // sizeを超えない2べきを求めておく(lowerBound用)
        beki_floor = 1;
        while(beki_floor <= _size / 2) {
            beki_floor <<= 1;
        }
    }

    // a[index] += x を行う
    void add(int index, T x) {
        assert(0 <= index && index < _size);
        int curIndex = index + 1;
        while(curIndex <= _size) {
            data[curIndex] += x;
            // 区間の長さ分だけ番号に足したところを更新していく
            curIndex += curIndex & (-curIndex);
        }
    }

    // a[left] + ... + a[right - 1] を求める
    T sum(int left, int right) const {
        assert(0 <= left && left < right && right <= _size);
        return sumFromFirst(right) - sumFromFirst(left);
    }

    // a[0] + ... a[x] >= w なる最小のxを求める(なければx = _size)
    int lowerBound(int w) const {
        if(w <= 0) return 0;
        int x = 0;
        for(int k = beki_floor; k > 0; k /= 2) {
            if(x + k <= _size && data[x + k] < w) {
                w -= data[x + k];
                x += k;
            }
        }
        return x;
    }

   private:
    int _size;
    vector<T> data;  // 1-base
    int beki_floor;  // _size以下の最大の2べき
    // a[0] + ... a[right - 1] の和を求める
    T sumFromFirst(int right) const {
        assert(0 <= right && right <= _size);
        if(right == 0) {
            return 0;
        }
        T ans = 0;
        int curIndex = right;
        while(curIndex > 0) {
            ans += data[curIndex];
            // 次に足すべき区間は番号から区間の長さだけ引いたもの
            curIndex -= curIndex & (-curIndex);
        }
        return ans;
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int q, k;
    cin >> q >> k;
    vector<ll> input(q); // -1ならクエリ2
    for(int i = 0; i < q; i++){
        int t;
        cin >> t;
        if(t == 1){
            cin >> input[i];
        } else{
            input[i] = -1;
        }
    }
    // 入力のうちクエリ1のものを取り出す
    vector<pair<ll, int>> query1;
    for(int i = 0; i < q; i++){
        if(input[i] == -1) continue;
        query1.emplace_back(input[i], i);
    }
    // 座標圧縮
    sort(ALL(query1));
    for(int i = 0; i < query1.size(); i++){
        input[query1[i].second] = i;
    }
    const int maxQuery1 = 200'000;
    fenwickTree<ll> BIT(maxQuery1);
    for(int i = 0; i < q; i++){
        // クエリ1
        if(input[i] != -1){
            BIT.add(input[i], 1);
        }
        // クエリ2 
        else {
            if(BIT.sum(0, maxQuery1) < k) cout << -1 << "\n";
            else{
                int ansIndex = BIT.lowerBound(k);
                cout << query1[ansIndex].first << "\n";
                BIT.add(ansIndex, -1);
            }
        }
    }
}
0