Submission #1295845

#TimeUsernameProblemLanguageResultExecution timeMemory
1295845lucas110550Festival (IOI25_festival)C++20
21 / 100
63 ms10580 KiB
#include <bits/stdc++.h> using namespace std; vector<int> max_coupons(int A, vector<int> P, vector<int> T) { int n = (int)P.size(); vector<pair<int,int>> L1; // (price, idx) for T[i] == 1 struct Coupon { long long p; long long t; int idx; }; vector<Coupon> L2; // (price, t, idx) for T[i] != 1 // Split coupons by type for (int i = 0; i < n; ++i) { if (T[i] == 1) { L1.emplace_back(P[i], i); } else { L2.push_back(Coupon{P[i], T[i], i}); } } // Sort L1 by price sort(L1.begin(), L1.end(), [](const pair<int,int>& a, const pair<int,int>& b) { return a.first < b.first; }); // Build prefix sums for type-1 coupons vector<long long> prefix1; prefix1.reserve(L1.size() + 1); prefix1.push_back(0); for (auto &item : L1) { long long price = item.first; long long next_val = prefix1.back() + price; prefix1.push_back(next_val); } // Custom comparator for L2 (replicates cmp_func) auto cmp_func = [](const Coupon &a, const Coupon &b) { // left = p1 * t1 * (t2 - 1) // right = p2 * t2 * (t1 - 1) __int128 left = (__int128)a.p * a.t * (b.t - 1); __int128 right = (__int128)b.p * b.t * (a.t - 1); if (left != right) { return left < right; } return a.idx < b.idx; }; sort(L2.begin(), L2.end(), cmp_func); int max_k = min(40, (int)L2.size()); const long long NEG_INF = -(long long)1e18; vector<long long> dp(max_k + 1, NEG_INF); vector<vector<int>> seq(max_k + 1); dp[0] = A; seq[0] = {}; // Knapsack-style DP over L2 for (int j = 0; j < (int)L2.size(); ++j) { long long p = L2[j].p; long long t = L2[j].t; int idx = L2[j].idx; for (int taken = max_k; taken >= 1; --taken) { if (dp[taken - 1] >= p) { long long current_token = dp[taken - 1] - p; long long new_token = current_token * t; if (new_token > (long long)1e18) { new_token = (long long)1e18; } if (new_token > dp[taken]) { dp[taken] = new_token; seq[taken] = seq[taken - 1]; seq[taken].push_back(idx); } } } } int best_count = 0; vector<int> best_seq; for (int taken = 0; taken <= max_k; ++taken) { if (dp[taken] < 0) continue; // m = bisect_right(prefix1, dp[taken]) - 1 // prefix1 is sorted non-decreasing int m = (int)(upper_bound(prefix1.begin(), prefix1.end(), dp[taken]) - prefix1.begin()) - 1; int total = taken + m; if (total > best_count) { best_count = total; vector<int> non1_indices = seq[taken]; vector<int> type1_indices; type1_indices.reserve(m); for (int i = 0; i < m; ++i) { type1_indices.push_back(L1[i].second); } best_seq.clear(); best_seq.insert(best_seq.end(), non1_indices.begin(), non1_indices.end()); best_seq.insert(best_seq.end(), type1_indices.begin(), type1_indices.end()); } } return best_seq; }
#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...