#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define vll vector #define vvvl vector #define vvl vector> #define VV(a, b, c, d) vector>(a, vector(b, c)) #define VVV(a, b, c, d) vector(a, vvl(b, vll (c, d))); #define re(c, b) for(ll c=0;c 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<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<ch[1]&&cur->ch[1]->cnt) { lca = cur->ch[1]; lcabit = Kbit - 1; lcaret = ret | (1ULL<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<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<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<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<ch[1]; }else if(cur->ch[0]->cnt>k){ cur = cur->ch[0]; }else{ k -= cur->ch[0]->cnt; ret |= (1ULL<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 st; int q, k;scanf("%d %d", &q, &k); for(int i=0;i