제출 #886179

#제출 시각아이디문제언어결과실행 시간메모리
886179nguyentunglam팀들 (IOI15_teams)C++17
100 / 100
1428 ms152164 KiB
#include<bits/stdc++.h> #define fi first #define se second #define endl "\n" #define ii pair<int, int> #define all(v) v.begin(), v.end() using namespace std; const int N = 5e5 + 10; pair<int, int> a[N]; int n; int last[N], pref[N], timer[N]; struct node { int left, right, sum; }; node T[N * 20 + 10]; int cnt, it[N], idx[N]; vector<pair<int, int> > rrh; void up(int s, int l, int r, int pos, int val) { if (l == r) { T[s].sum += val; return; } int mid = l + r >> 1; if (pos <= mid) { T[++cnt] = T[T[s].left]; T[s].left = cnt; up(T[s].left, l, mid, pos, val); } else { T[++cnt] = T[T[s].right]; T[s].right = cnt; up(T[s].right, mid + 1, r, pos, val); } T[s].sum = T[T[s].left].sum + T[T[s].right].sum; } int get(int s, int l, int r, int from, int to) { if (l > to || r < from || !s) return 0; if (from <= l && r <= to) return T[s].sum; int mid = l + r >> 1; return get(T[s].left, l, mid, from, to) + get(T[s].right, mid + 1, r, from, to); } int tree_idx (int x) { return upper_bound(all(rrh), make_pair(x, 0)) - rrh.begin() + 1; } void init(int _n, int A[], int B[]) { n = _n; for(int i = 1; i <= n; i++) { a[i] = make_pair(A[i - 1], B[i - 1]); } sort(a + 1, a + n + 1); for(int i = 1; i <= n; i++) { rrh.emplace_back(a[i].second, i); } sort(all(rrh)); rrh.resize(unique(all(rrh)) - rrh.begin()); for(int i = 1; i <= n; i++) { int old = a[i].second; a[i].second = upper_bound(all(rrh), make_pair(a[i].second, i)) - rrh.begin(); idx[old] = max(idx[old], a[i].second); } for(int i = 1; i <= n; i++) { if (idx[i] == 0) idx[i] = idx[i - 1]; } for(int i = 1, j = 1; i <= n; i++) { T[it[i] = ++cnt] = T[it[i - 1]]; while (j <= n && a[j].first == i) { up(it[i], 1, n, a[j].second, 1); j++; } } // for(int i = 1; i <= n; i++) cout << a[i].first << " " << a[i].second << endl; } int can (int m, int k[]) { sort(k, k + m); for(int i = 0, p = 0; i < m; i++) { int sz = k[i]; auto calc = [&] (int x) { int total = get(it[sz], 1, n, 1, x); int lost = 0; if (!p) return total; int l = 1, r = p, pos = 0; while (l <= r) { int mid = l + r >> 1; if (last[mid] >= x) { pos = mid; l = mid + 1; } else r = mid - 1; } lost = pref[p] - pref[pos]; if (pos) { last[p + 1] = 0; lost += get(it[timer[pos]], 1, n, last[pos + 1] + 1, x); } return total - lost; }; // if (i == 1) cout << calc(1) << endl; // if (i == 0) { // cout << calc(1) << endl; // return 0; // } int not_use = calc(idx[sz - 1]); // if (i == 0) cout << calc(1) << endl; // if (i == 0) { // cout << sz - 1 << endl; // cout << idx[sz - 1] << endl; // cout << not_use << endl; // } int l = 1, r = n, smallest = 0; while (l <= r) { int mid = l + r >> 1; if (calc(mid) - not_use >= sz) { smallest = mid; r = mid - 1; } else l = mid + 1; } // cout << smallest << endl; // cout << calc(smallest) << " " << not_use << endl; if (!smallest) return 0; while (p && last[p] <= smallest) p--; if (p) { pref[p] = get(it[timer[p]], 1, n, smallest + 1, last[p]); if (p) pref[p] += pref[p - 1]; } ++p; pref[p] = pref[p - 1] + get(it[sz], 1, n, 1, smallest); last[p] = smallest; timer[p] = sz; } return 1; } #ifdef ngu int32_t main() { freopen ("task.inp", "r", stdin); freopen ("task.out", "w", stdout); int n; cin >> n; int *A = (int *)malloc(sizeof(int) * (unsigned int)N); int *B = (int *)malloc(sizeof(int) * (unsigned int)N); for(int i = 0; i < n; i++) cin >> A[i] >> B[i]; init(n, A, B); int q; cin >> q; while (q--) { int m; cin >> m; int *k = (int *)malloc(sizeof(int) * (unsigned int)m); for(int i = 0; i < m; i++) cin >> k[i]; cout << can(m, k) << endl; } } #endif // ngu

컴파일 시 표준 에러 (stderr) 메시지

teams.cpp: In function 'void up(int, int, int, int, int)':
teams.cpp:32:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   32 |   int mid = l + r >> 1;
      |             ~~^~~
teams.cpp: In function 'int get(int, int, int, int, int)':
teams.cpp:49:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   49 |   int mid = l + r >> 1;
      |             ~~^~~
teams.cpp: In function 'int tree_idx(int)':
teams.cpp:54:63: warning: conversion from '__gnu_cxx::__normal_iterator<std::pair<int, int>*, std::vector<std::pair<int, int> > >::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
   54 |   return upper_bound(all(rrh), make_pair(x, 0)) - rrh.begin() + 1;
      |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
teams.cpp: In function 'void init(int, int*, int*)':
teams.cpp:75:68: warning: conversion from '__gnu_cxx::__normal_iterator<std::pair<int, int>*, std::vector<std::pair<int, int> > >::difference_type' {aka 'long int'} to 'int' may change value [-Wconversion]
   75 |     a[i].second = upper_bound(all(rrh), make_pair(a[i].second, i)) - rrh.begin();
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
teams.cpp: In lambda function:
teams.cpp:105:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  105 |         int mid = l + r >> 1;
      |                   ~~^~~
teams.cpp: In function 'int can(int, int*)':
teams.cpp:134:19: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  134 |       int mid = l + r >> 1;
      |                 ~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...