제출 #1153900

#제출 시각아이디문제언어결과실행 시간메모리
1153900simuyuIndex (COCI21_index)C++20
0 / 110
347 ms589824 KiB
#include <bits/stdc++.h> using namespace std; #define f first #define s second #define ll long long ll N, Q; ll p[200005]; struct sum_node { // point update range query sum segment tree ll s, e, m, val; sum_node *l, *r; sum_node (int _s, int _e): s(_s), e(_e), m((_s+_e)/2), val(0) { if (s != e) { // not leaf l = new sum_node(s, m); r = new sum_node(m+1, e); } } void increment(ll idx, ll v) { if (s==e) { // leaf val += v; return; } else if (idx>m) { r->increment(idx, v); } else { l->increment(idx, v); } val = l->val + r->val; } ll sum(ll x, ll y) { // inclusive of both if ((x>y) || (x>e) || (y<s)) return 0; // invalid input if (s==e) return val; // if completely within range if ((x<s) && (y>e)) return val; return l->sum(x, y) + r->sum(x, y); } }; struct node { ll s, e, m; //int counts[200005]; sum_node *counts; node *l, *r; node (int _s, int _e) : s(_s), e(_e), m((_s+_e)/2) { if (s != e) { //not leaf node l = new node(s, m); r = new node(m+1, e); } //for (int i=0; i<200005; i++) counts[i]=0; counts = new sum_node(0, 200005); } void update (ll idx, ll v) { if (s==e) { // leaf. counts->increment(v, 1); return; } else if (idx>m) { r->update(idx, v); } else { l->update(idx, v); } // this is a counts segment tree... counts->increment(v, 1); // haha it's actually just this } ll get_h_cnt(ll h, ll x, ll y) { // inclusive of both endpoints // sum of all the counts[h]. if ((x>y) || (x>e) || (y<s)) return 0; // invalid if (x==y) { // leaf return counts->sum(h, 200005); } // if completely within range if ((s>=x) && (e<=y)) { return counts->sum(h, 200005); } // else, consider children return r->get_h_cnt(h, x, y) + l->get_h_cnt(h, x, y); // if out of range it'll return 0 so this is fine } bool try_h(ll h, ll x, ll y) { return get_h_cnt(h, x, y) >= h; } } *root; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> N >> Q; root = new node(1, N); for (ll i=0; i<N; i++) { cin >> p[i]; root->update(i+1, p[i]); } /*cout << "COUNTS: "; for (ll i=0; i<N; i++) { cout << root->counts[i] << ' '; } cout << endl;*/ ll l, r; ll low, high, mid; for (ll q=0; q<Q; q++) { cin >> l >> r; low = 0; high = r-l+1; while (high-low > 1) { mid = (high+low)/2; //cout << "TRY H=" << mid << "; COUNT=" << root->get_h_cnt(mid, l, r) << endl; if (root->try_h(mid, l, r)) { // means that mid is okay low = mid; // so low is guaranteed okay, as try_h(mid) or 0 (0 is always attainable) } else { high = mid; } } if (root->try_h(high, l, r)) { // if high works too, then just swap w low. in the end, low wld the the one we use swap(low, high); } // low is the answer cout << low << endl; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...