結果
問題 | No.649 ここでちょっとQK! |
ユーザー | tonegawa |
提出日時 | 2020-10-02 04:24:55 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 553 ms / 3,000 ms |
コード長 | 7,953 bytes |
コンパイル時間 | 1,088 ms |
コンパイル使用メモリ | 117,340 KB |
実行使用メモリ | 247,936 KB |
最終ジャッジ日時 | 2024-07-07 18:37:47 |
合計ジャッジ時間 | 9,713 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 34 ms
5,376 KB |
testcase_04 | AC | 96 ms
16,128 KB |
testcase_05 | AC | 98 ms
16,128 KB |
testcase_06 | AC | 79 ms
5,376 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 2 ms
5,376 KB |
testcase_10 | AC | 2 ms
5,376 KB |
testcase_11 | AC | 2 ms
5,376 KB |
testcase_12 | AC | 253 ms
128,640 KB |
testcase_13 | AC | 254 ms
128,768 KB |
testcase_14 | AC | 256 ms
119,040 KB |
testcase_15 | AC | 262 ms
128,768 KB |
testcase_16 | AC | 250 ms
128,896 KB |
testcase_17 | AC | 290 ms
140,800 KB |
testcase_18 | AC | 310 ms
152,960 KB |
testcase_19 | AC | 336 ms
164,480 KB |
testcase_20 | AC | 361 ms
176,768 KB |
testcase_21 | AC | 390 ms
188,544 KB |
testcase_22 | AC | 410 ms
200,576 KB |
testcase_23 | AC | 451 ms
212,480 KB |
testcase_24 | AC | 471 ms
224,384 KB |
testcase_25 | AC | 508 ms
236,288 KB |
testcase_26 | AC | 553 ms
247,936 KB |
testcase_27 | AC | 2 ms
5,376 KB |
testcase_28 | AC | 3 ms
5,376 KB |
testcase_29 | AC | 2 ms
5,376 KB |
testcase_30 | AC | 54 ms
8,320 KB |
testcase_31 | AC | 49 ms
8,448 KB |
testcase_32 | AC | 2 ms
5,376 KB |
testcase_33 | AC | 2 ms
5,376 KB |
testcase_34 | AC | 2 ms
5,376 KB |
testcase_35 | AC | 2 ms
5,376 KB |
ソースコード
#include <iostream> #include <string> #include <vector> #include <array> #include <queue> #include <deque> #include <algorithm> #include <set> #include <map> #include <bitset> #include <cmath> #include <functional> #include <cassert> #include <iomanip> #define vll vector<ll> #define vvvl vector<vvl> #define vvl vector<vector<ll>> #define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c)) #define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d))); #define re(c, b) for(ll c=0;c<b;c++) #define all(obj) (obj).begin(), (obj).end() typedef long long int ll; typedef long double ld; using namespace std; const long long ERROR = (1ULL<<63) - 1; template<typename E> struct BinaryTrieMultiset64{ private: struct node{ node* ch[2]; E cnt; node(): ch{nullptr, nullptr}, cnt(0){} }; const uint64_t UINTMAX = ((1ULL<<63) - 1) + (1ULL<<63); node* root = new node(); inline bool inner_insert(uint64_t x, E add = 1){ int Kbit = 63; node* cur = root; while((Kbit+1)){ bool nxt = (x>>Kbit)&1; if(!cur->ch[nxt]){ auto to = new node(); cur->ch[nxt] = to; } cur->cnt += add; cur = cur->ch[nxt]; Kbit--; } cur->cnt += add; return true; } inline E inner_erase(node* cur, int Kbit, uint64_t x, E k = -1){ if(Kbit==-1){ E erase_num = (k==-1?cur->cnt:std::min(cur->cnt, k)); cur->cnt -= erase_num; return erase_num; } bool nxt = (x>>Kbit)&1; if(!cur->ch[nxt]||cur->ch[nxt]->cnt==0) return false; E erase_num = inner_erase(cur->ch[nxt], Kbit-1, x, k); if(erase_num){ cur->cnt -= erase_num; return true; } return false; } inline E inner_find(node* cur, int Kbit, uint64_t x){ if(Kbit==-1) return cur->cnt; bool nxt = (x>>Kbit)&1; if(!cur->ch[nxt]||cur->ch[nxt]->cnt==0) return 0; return inner_find(cur->ch[nxt], Kbit-1, x); } inline uint64_t inner_max(){ node* cur = root; uint64_t ret = 0; int Kbit = 63; while(cur->ch[0]||cur->ch[1]){ if(cur->ch[1]) ret |= (1ULL<<Kbit), cur = cur->ch[1]; else cur = cur->ch[0]; Kbit--; } return ret; } inline uint64_t inner_min(){ node* cur = root; uint64_t ret = 0; int Kbit = 63; while(cur->ch[0]||cur->ch[1]){ if(cur->ch[0]) cur = cur->ch[0]; else ret |= (1ULL << Kbit), cur = cur->ch[1]; Kbit--; } return ret; } inline uint64_t inner_upper_bound(uint64_t x){ int Kbit = 63; node* lca = nullptr;//最も深い位置で右に別れたノード int lcabit; uint64_t ret = 0; uint64_t lcaret = 0; node* cur = root; while(Kbit){ bool nxt = (x>>Kbit)&1; if(nxt){ if(!cur->ch[1]||cur->ch[1]->cnt==0) break; else cur = cur->ch[1]; ret |= (1ULL<<Kbit); }else{ if(cur->ch[1]&&cur->ch[1]->cnt) { lca = cur->ch[1]; lcabit = Kbit - 1; lcaret = ret | (1ULL<<Kbit); } cur = cur->ch[0]; } Kbit--; } if(!(x&1)&&cur->ch[1]&&cur->ch[1]->cnt) return ret + 1; if(!lca) return UINTMAX; cur = lca; while(lcabit){ if(cur->ch[0]&&cur->ch[0]->cnt) cur = cur->ch[0]; else{ lcaret |= (1ULL<<lcabit); cur = cur->ch[1]; } lcabit--; } if(!cur->ch[0]||cur->ch[0]->cnt==0) lcaret++; return lcaret; } inline uint64_t inner_reverse_upper_bound(uint64_t x){ int Kbit = 63; node* lca = nullptr;//最も深い位置で右に別れたノード int lcabit; uint64_t ret = 0; uint64_t lcaret = 0; node* cur = root; while(Kbit){ bool nxt = (x>>Kbit)&1; if(!nxt){ if(!cur->ch[0]||cur->ch[0]->cnt==0) break; else cur = cur->ch[0]; }else{ if(cur->ch[0]&&cur->ch[0]->cnt) { lca = cur->ch[0]; lcabit = Kbit - 1; lcaret = ret; } cur = cur->ch[1]; ret |= (1ULL<<Kbit); } Kbit--; } if((x&1)&&cur->ch[0]&&cur->ch[0]->cnt) return ret; if(!lca) return UINTMAX; cur = lca; while(lcabit){ if(cur->ch[1]&&cur->ch[1]->cnt) { cur = cur->ch[1]; lcaret |= (1ULL<<lcabit); }else{ cur = cur->ch[0]; } lcabit--; } if(cur->ch[1]&&cur->ch[1]->cnt) lcaret++; return lcaret; } inline uint64_t inner_kth_element(E k){ int Kbit = 63; node* cur = root; uint64_t ret = 0; while(Kbit){ if(!cur->ch[0]){ ret |= (1ULL<<Kbit); cur = cur->ch[1]; }else if(cur->ch[0]->cnt>k){ cur = cur->ch[0]; }else{ k -= cur->ch[0]->cnt; ret |= (1ULL<<Kbit); cur = cur->ch[1]; } Kbit--; } if(!cur->ch[0]||cur->ch[0]->cnt<=k) ret++; return ret; } inline E inner_under_count(uint64_t x){ int Kbit = 63; node* cur = root; E ret = 0; while(Kbit){ bool nxt = (x>>Kbit)&1; if(nxt){ if(cur->ch[0]) ret += cur->ch[0]->cnt; if(!cur->ch[1]||cur->ch[1]->cnt==0) return ret; else cur = cur->ch[1]; }else{ if(!cur->ch[0]||cur->ch[0]->cnt==0) return ret; else cur = cur->ch[0]; } Kbit--; } if(x&1 && cur->ch[0]) ret += cur->ch[0]->cnt; return ret; } public: //templateのEはsizeの型(要素の和の最大数) inline E size(){ return root->cnt; } //1個挿入 inline bool insert(long long x){ if(x==ERROR) return false; uint64_t y = (uint64_t)(x + (1ULL<<63)); return inner_insert(y); } //全て消してその個数を返す inline E erase(long long x){ if(x==ERROR) return 0; uint64_t y = (uint64_t)(x + (1ULL<<63)); return inner_erase(root, 63, y); } //k個挿入 inline bool insert_k(long long x, E k){ if(x==ERROR) return false; uint64_t y = (uint64_t)(x + (1ULL<<63)); return inner_insert(y, k); } //k個削除を試みて消した個数を返す inline E erase_k(long long x, E k){ if(x==ERROR) return 0; uint64_t y = (uint64_t)(x + (1ULL<<63)); return inner_erase(root, 63, y, k); } //xの個数を返す, multisetのcountを兼ねている inline E find(long long x){ if(x==ERROR) return 0; uint64_t y = (uint64_t)(x + (1ULL<<63)); return inner_find(root, 63, y); } inline long long max(){ if(size()==0) return ERROR; return (long long)inner_max() - (1ULL<<63); } inline long long min(){ if(size()==0) return ERROR; return (long long)inner_min() - (1ULL<<63); } inline long long lower_bound(long long x){ uint64_t y = (uint64_t)(x + (1ULL<<63) - 1); return (long long)inner_upper_bound(y) - (1LL<<63); } inline long long upper_bound(long long x){ if(x==ERROR) return ERROR; uint64_t y = (uint64_t)(x + (1ULL<<63)); return (long long)inner_upper_bound(y) - (1LL<<63); } inline long long reverse_upper_bound(long long x){ uint64_t y = (uint64_t)(x + (1ULL<<63)); return (long long)inner_reverse_upper_bound(y) - (1LL<<63); } inline long long reverse_lower_bound(long long x){ if(x==ERROR) return ERROR; uint64_t y = (uint64_t)(x + (1ULL<<63) + 1); return (long long)inner_reverse_upper_bound(y) - (1LL<<63); } //k番目の値を返す(0-indexed) O(logN) inline long long kth_element(E k){ if(size()<=k) return ERROR; return (long long)inner_kth_element(k) - (1LL<<63); } //x未満の値を数える O(logN) inline E under_count(long long x){ uint64_t y = (uint64_t)(x + (1ULL<<63)); return inner_under_count(y); } }; int main(){ BinaryTrieMultiset64<int> st; int q, k;scanf("%d %d", &q, &k); for(int i=0;i<q;i++){ ll x;scanf("%lld", &x); if(x==1){ ll y;scanf("%lld", &y); st.insert(y); }else{ ll t = st.kth_element(k-1); if(t==ERROR) printf("%d\n", -1); else{ st.erase_k(t, 1); printf("%lld\n", t); } } } }