제출 #1129314

#제출 시각아이디문제언어결과실행 시간메모리
1129314antonnNaan (JOI19_naan)C++20
29 / 100
487 ms32564 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define ld long double #define all(a) a.begin(), a.end() #define rall(a) a.rbegin(), a.rend() int n, L; vector<vector<int>> v; vector<vector<ll>> pref; struct Frac { ll p; ll q; Frac(ll a = 0, ll b = 1) : p(a), q(b) {} void reduct() { ll d = __gcd(p, q); p /= d; q /= d; } }; bool operator <= (Frac a, Frac b) { return (__int128) a.p * b.q <= (__int128) b.p * a.q; } bool operator < (Frac a, Frac b) { return (__int128) a.p * b.q < (__int128) b.p * a.q; } Frac operator + (Frac a, Frac b) { Frac c; c.p = a.p * b.q + b.p * a.q; c.q = a.q * b.q; return c; } Frac operator - (Frac a, Frac b) { Frac c; c.p = a.p * b.q - b.p * a.q; c.q = a.q * b.q; return c; } Frac operator - (ll x, Frac f) { return {x * f.q - f.p, f.q}; } Frac operator - (Frac f, ll x) { return {f.p - x * f.q, f.q}; } Frac operator * (Frac f, ll x) { f.p *= x; return f; } Frac operator / (Frac f, ll x) { f.q *= x; return f; } int32_t main() { if (1) { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); } cin >> n >> L; v.assign(n + 1, vector<int>(L + 2)); vector<Frac> need(n + 1); for (int i = 1; i <= n; i += 1) { ll sum = 0; for (int j = 1; j <= L; j += 1) { cin >> v[i][j]; sum += v[i][j]; } v[i][L + 1] = 1; need[i] = {sum, n}; } vector<vector<Frac>> cuts(n + 1); for (int i = 1; i <= n; i += 1) { Frac pos = {0, 1}; Frac c = {0, 1}; Frac sum = {0, 1}; int full = 0; cuts[i].push_back({0, 1}); while (full != L) { if (sum + (full + 1 - c) * v[i][full + 1] <= need[i]) { sum = sum + (full + 1 - c) * v[i][full + 1]; full += 1; c = {full, 1}; } else { c = c + (need[i] - sum) / v[i][full + 1]; c.reduct(); cuts[i].push_back(c); sum = {0, 1}; } } cuts[i].push_back({L, 1}); } vector<int> rem(n); iota(all(rem), 1); vector<pair<int, Frac>> sol; Frac last = {-1, 1}; for (int it = 1; it <= n; it += 1) { pair<int, Frac> best = {-1, {L, 1}}; for (int i : rem) { int low = 0, high = n - 1, sol = -1; while (low <= high) { int mid = (low + high) / 2; if (last <= cuts[i][mid]) { sol = mid; high = mid - 1; } else { low = mid + 1; } } if (sol != -1) { if (cuts[i][sol + 1] <= best.second) { best = {i, cuts[i][sol + 1]}; } } } if (best.first == -1) { cout << -1 << "\n"; return 0; } sol.push_back(best); vector<int> nw; for (auto i : rem) { if (i != best.first) { nw.push_back(i); } } rem = nw; last = best.second; } for (int i = 0; i < sol.size() - 1; i += 1) { int who = sol[i].first; Frac split = sol[i].second; assert(split.p != 0); cout << split.p << " " << split.q << "\n"; } for (int i = 0; i < sol.size(); i += 1) { int who = sol[i].first; Frac split = sol[i].second; cout << who << " "; } cout << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...