Submission #1254700

#TimeUsernameProblemLanguageResultExecution timeMemory
1254700fasterthanyouFestival (IOI25_festival)C++20
5 / 100
44 ms9652 KiB
#include <bits/stdc++.h> using namespace std; vector<int> max_coupons(int A, vector<int> P, vector<int> T) { using ll = long long; const int N = (int)P.size(); // Split into T=1 and multipliers T>=2 vector<pair<int,int>> t1; // (price, idx) struct MItem { long long key; // w(T) * P key int p, t, idx; }; vector<MItem> mult; int maxP = 0; ll sumT1 = 0; auto weight = [](int t) -> int { // Sorting by s = P*T/(T-1). Multiply by 6 to avoid fractions: // T=2 -> 12, T=3 -> 9, T=4 -> 8 if (t == 2) return 12; if (t == 3) return 9; // t == 4 return 8; }; for (int i = 0; i < N; ++i) { maxP = max(maxP, P[i]); if (T[i] == 1) { t1.emplace_back(P[i], i); sumT1 += (ll)P[i]; } else { int w = weight(T[i]); mult.push_back(MItem{ (ll)w * (ll)P[i], P[i], T[i], i }); } } // Sort multipliers by key, then by price, then by index for determinism sort(mult.begin(), mult.end(), [](const MItem& a, const MItem& b) { if (a.key != b.key) return a.key < b.key; if (a.p != b.p) return a.p < b.p; if (a.t != b.t) return a.t < b.t; return a.idx < b.idx; }); // Sort T=1 by ascending price, tie-break by index sort(t1.begin(), t1.end(), [](const pair<int,int>& a, const pair<int,int>& b){ if (a.first != b.first) return a.first < b.first; return a.second < b.second; }); // Prefix sums for T=1 vector<ll> pref1(1, 0); pref1.reserve(t1.size() + 1); for (auto &e : t1) pref1.push_back(pref1.back() + (ll)e.first); // Cap to avoid overflow while preserving correctness: // Must be >= max price to not break feasibility checks, and >= sum of T1 // so we don't undercount purchasable T1. ll cap = sumT1 + (ll)maxP + 1; // Simulate all feasible prefixes of multipliers vector<ll> after; // tokens after buying first k multipliers after.reserve(mult.size() + 1); ll tokens = (ll)A; after.push_back(tokens); int F = 0; // number of feasible multipliers in order for (int i = 0; i < (int)mult.size(); ++i) { tokens = min(tokens, cap); if (tokens < mult[i].p) break; // can't afford next multiplier ll ntok = (tokens - (ll)mult[i].p) * (ll)mult[i].t; if (ntok > cap) ntok = cap; tokens = ntok; after.push_back(tokens); ++F; } // For each feasible prefix k, buy as many T=1 as possible and track the best int best_k = 0, best_r = 0; ll best_total = -1; for (int k = 0; k <= F; ++k) { ll cur = after[k]; // r = largest with pref1[r] <= cur int r = (int)(upper_bound(pref1.begin(), pref1.end(), cur) - pref1.begin()) - 1; ll total = (ll)k + (ll)r; if (total > best_total) { best_total = total; best_k = k; best_r = r; } else if (total == best_total) { // Optional tie-breaker: prefer more multipliers if (k > best_k) { best_k = k; best_r = r; } } } // Build the actual purchase order: first the chosen multipliers, then chosen T=1 vector<int> order; order.reserve(best_k + best_r); for (int i = 0; i < best_k; ++i) order.push_back(mult[i].idx); for (int i = 0; i < best_r; ++i) order.push_back(t1[i].second); return order; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...