Submission #242950

#TimeUsernameProblemLanguageResultExecution timeMemory
242950dung11112003Jousting tournament (IOI12_tournament)C++11
100 / 100
185 ms14188 KiB
#include <bits/stdc++.h> #define taskname "" #define pb push_back #define eb emplace_back #define fi first #define se second #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define for0(i, n) for (int i = 0; i < (int)(n); ++i) #define for1(i, n) for (int i = 1; i <= (int)(n); ++i) #define ford(i, n) for (int i = (int)(n) - 1; i >= 0; --i) #define fore(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i) using namespace std; typedef long long ll; typedef long double ld; typedef complex <ld> cd; typedef vector <cd> vcd; typedef vector <int> vi; template<class T> using v2d = vector <vector <T> >; template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; } template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; } mt19937 rng(chrono::system_clock::now().time_since_epoch().count()); namespace firstSub { list <int> a; int solve(int n, int m, int val, int *K, int *S, int *E) { int r = 0, p; for0(pos, n) { a.clear(); for0(i, pos) { a.insert(a.end(), K[i]); } a.insert(a.end(), val); for (int i = pos; i < n; i++) { a.insert(a.end(), K[i]); } int cnt = 0; for0(i, m) { auto it = a.begin(); advance(it, S[i]); int winner = 0; bool joined = 0; for (int j = S[i]; j <= E[i]; j++) { uax(winner, *it); joined |= (*it == val); it++; } if (joined) { if (winner == val) { ++cnt; } else { break; } } it = a.begin(); advance(it, S[i]); for (int j = S[i]; j <= E[i]; j++) { if (*it < winner) { it = a.erase(it); } else { it++; } } } if (uax(r, cnt)) { p = pos; } } return p; } } namespace secondSub { const int maxN = 5e3 + 10; int f[maxN * 4], L, R, val, d[maxN][20]; bool lazy[maxN * 4]; void build(int x, int lo, int hi) { if (lo == hi) { f[x] = 1; return; } int mid = (lo + hi) / 2; build(x * 2, lo, mid); build(x * 2 + 1, mid + 1, hi); f[x] = f[x * 2] + f[x * 2 + 1]; } void down(int x) { bool d = lazy[x]; if (d) { lazy[x] = 0; lazy[x * 2] = lazy[x * 2 + 1] = 1; f[x * 2] = f[x * 2 + 1] = 0; } } void update(int x, int lo, int hi) { if (lo > R || hi < L) { return; } if (lo >= L && hi <= R) { f[x] = 0; lazy[x] = 1; return; } down(x); int mid = (lo + hi) / 2; update(x * 2, lo, mid); update(x * 2 + 1, mid + 1, hi); f[x] = f[x * 2] + f[x * 2 + 1]; } int query(int l, int r) { int h = 31 - __builtin_clz(r - l + 1); return max(d[l][h], d[r - (1 << h) + 1][h]); } void recal(int n, int idx, int val) { d[idx][0] = val; for (int j = 1; (1 << j) <= n; j++) { for (int i = idx; i + (1 << j) - 1 >= idx && i >= 0; i--) { if (i + (1 << j) - 1 < n) { d[i][j] = max(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]); } } } } int findPos(int x, int lo, int hi, int sum) { if (val <= 0) { return -1; } if (lo == hi) { return lo; } down(x); int mid = (lo + hi) / 2; if (f[x * 2] + sum >= val) { return findPos(x * 2, lo, mid, sum); } return findPos(x * 2 + 1, mid + 1, hi, sum + f[x * 2]); } int solve(int n, int m, int target, int *K, int *S, int *E) { vector <int> l(m), r(m); build(1, 0, n - 1); for0(i, m) { val = E[i] + 1; r[i] = findPos(1, 0, n - 1, 0); val = S[i]; l[i] = findPos(1, 0, n - 1, 0) + 1; L = l[i], R = r[i] - 1; update(1, 0, n - 1); } int ans = -1, p; d[0][0] = target; for0(i, n - 1) { d[i + 1][0] = K[i]; } for (int j = 1; (1 << j) <= n; j++) { for (int i = 0; i + (1 << j) - 1 < n; i++) { d[i][j] = max(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]); } } for0(pos, n) { int cnt = 0; for0(i, m) { if (l[i] > pos || r[i] < pos) { continue; } cnt += query(l[i], r[i]) == target; } if (pos < n - 1) { recal(n, pos, K[pos]); recal(n, pos + 1, target); } if (uax(ans, cnt)) { p = pos; } } return p; } } namespace fullSub { const int maxN = 1e5 + 10; int f[maxN * 4], g[maxN * 4], L, R, idx, val; bool lazy[maxN * 4]; void build(int x, int lo, int hi) { if (lo == hi) { f[x] = 1; return; } int mid = (lo + hi) / 2; build(x * 2, lo, mid); build(x * 2 + 1, mid + 1, hi); f[x] = f[x * 2] + f[x * 2 + 1]; } void down(int x) { bool d = lazy[x]; if (d) { lazy[x] = 0; lazy[x * 2] = lazy[x * 2 + 1] = 1; f[x * 2] = f[x * 2 + 1] = 0; } } void update(int x, int lo, int hi) { if (lo > R || hi < L) { return; } if (lo >= L && hi <= R) { f[x] = 0; lazy[x] = 1; return; } down(x); int mid = (lo + hi) / 2; update(x * 2, lo, mid); update(x * 2 + 1, mid + 1, hi); f[x] = f[x * 2] + f[x * 2 + 1]; } void modify(int x, int lo, int hi) { if (lo == hi && lo == idx) { g[x] = val; return; } int mid = (lo + hi) / 2; if (idx <= mid) { modify(x * 2, lo, mid); } else { modify(x * 2 + 1, mid + 1, hi); } g[x] = max(g[x * 2], g[x * 2 + 1]); } int query(int x, int lo, int hi) { if (lo > R || hi < L) { return 0; } if (lo >= L && hi <= R) { return g[x]; } int mid = (lo + hi) / 2; return max(query(x * 2, lo, mid), query(x * 2 + 1, mid + 1, hi)); } int findPos(int x, int lo, int hi, int sum) { if (val <= 0) { return -1; } if (lo == hi) { return lo; } down(x); int mid = (lo + hi) / 2; if (f[x * 2] + sum >= val) { return findPos(x * 2, lo, mid, sum); } return findPos(x * 2 + 1, mid + 1, hi, sum + f[x * 2]); } int solve(int n, int m, int target, int *K, int *S, int *E) { vector <int> l(m), r(m); build(1, 0, n - 1); for0(i, m) { val = E[i] + 1; r[i] = findPos(1, 0, n - 1, 0); val = S[i]; l[i] = findPos(1, 0, n - 1, 0) + 1; L = l[i], R = r[i] - 1; update(1, 0, n - 1); } vector <vector <int>> start(n), finish(n); for0(i, m) { start[l[i]].eb(i); finish[r[i]].eb(i); } int ans = -1, p, cnt = 0; idx = 0, val = target; modify(1, 0, n - 1); for0(i, n - 1) { idx = i + 1, val = K[i]; modify(1, 0, n - 1); } for0(i, m) { if (l[i] <= 0 && r[i] >= 0) { L = l[i], R = r[i]; cnt += (query(1, 0, n - 1) == target); } } if (uax(ans, cnt)) { p = 0; } fore(pos, 1, n - 1) { for (auto &id: finish[pos - 1]) { L = l[id], R = r[id];; cnt -= (query(1, 0, n - 1) == target); } idx = pos - 1, val = K[pos - 1]; modify(1, 0, n - 1); idx = pos, val = target; modify(1, 0, n - 1); for (auto &id: start[pos]) { L = l[id], R = r[id]; cnt += (query(1, 0, n - 1) == target); } if (uax(ans, cnt)) { p = pos; } } return p; } } int GetBestPosition(int n, int m, int val, int *K, int *S, int *E) { // if (n <= 500) // { // return firstSub::solve(n, m, val, K, S, E); // } // else if (n <= 5000) // { // return secondSub::solve(n, m, val, K, S, E); // } // else // { // return fullSub::solve(n, m, val, K, S, E); // } return fullSub::solve(n, m, val, K, S, E); }

Compilation message (stderr)

tournament.cpp: In function 'int secondSub::solve(int, int, int, int*, int*, int*)':
tournament.cpp:237:16: warning: 'p' may be used uninitialized in this function [-Wmaybe-uninitialized]
         return p;
                ^
tournament.cpp: In function 'int firstSub::solve(int, int, int, int*, int*, int*)':
tournament.cpp:96:16: warning: 'p' may be used uninitialized in this function [-Wmaybe-uninitialized]
         return p;
                ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...