Submission #1012796

#TimeUsernameProblemLanguageResultExecution timeMemory
1012796ProtonDecay314Carnival Tickets (IOI20_tickets)C++17
100 / 100
765 ms111612 KiB
/* YOOOO IT WORKED FIRST TRY???? WHAT HOW HOW HOW HOW HOW HOW HOW HOW HOW HOW HOW HOW EYOO?? NANI?? HOW DID I NOT MAKE ANY BUGS??? HUH?? WHAT?? AHHHHHHHHHHHHHHHHH HOW DOES THIS NOT HAVE BUGS??? WHAT?? IT WORKS?? WHY??? HUH??? THAT'S CRAZY!! also, I avoided using a pqueue!! >:) HAHAHAH I GOT AWAY BY SORTING STUFF REPEATEDLY! TAKE THAT, DATA STRUCTURES! WAHOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO */ #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef vector<ll> vll; typedef vector<vll> vvll; typedef vector<int> vi; typedef vector<vi> vvi; typedef pair<int, int> pi; typedef pair<ll, ll> pll; typedef vector<pi> vpi; typedef vector<pll> vpll; typedef vector<vpi> vvpi; typedef vector<vpll> vvpll; typedef vector<bool> vb; #define IOS ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); #define L(varll, mn, mx) for(ll varll = (mn); varll < (mx); varll++) #define LR(varll, mx, mn) for(ll varll = (mx); varll > (mn); varll--) #define LI(vari, mn, mx) for(int vari = (mn); vari < (mx); vari++) #define LIR(vari, mx, mn) for(int vari = (mx); vari > (mn); vari--) #define INPV(varvec) for(auto& varveci : (varvec)) cin >> varveci #define fi first #define se second #define pb push_back #define INF(type) numeric_limits<type>::max() #define NINF(type) numeric_limits<type>::min() #define TCASES int t; cin >> t; while(t--) #ifndef DEBUG #include "tickets.h" #endif #ifdef DEBUG vvi ta; void allocate_tickets(const vvi& a_ta) { LI(i, 0, (int)ta.size()) { copy(a_ta[i].begin(), a_ta[i].end(), back_inserter(ta[i])); } } #endif ll find_maximum(int k, vvi x) { int n = x.size(), m = x[0].size(); vvi talloc; LI(i, 0, n) { vi tallocr(m, -1); talloc.pb(tallocr); } ll ans = 0ll; /* It's time to full point this problem! >:D So uhh for each color, pick k tickets it's always optimal to pick a prefix/suffix Tapos, the total number of "max" tickets must equal kn / 2 Same for min tickets same thing as subtask 1, let's start with like, all mins Then, we pair each minimum with the maximum tapos, the oppcost is just min + max again, since by removing a min we increase by that value, tapos we increase by max ulit, so the net effect is just the sum of min + max Hmm, wait, is it possible, given some initial picking of max and min, that we can assign the k rounds so that it works?? hmm +00000 +++000 +++++0 0----- 000--- 00000- +00000|0----- ++0000|10---- ++++++|210122 0-----|-22211 00----|--1000 000000|------ Consider nk points. Now, consider the median line Oh, we can do some kind of pqueue siguro, no? haha or kailangan ba? hmm, kasi like, pwede naman i-sort ulit in O(n log n) Tapos, we have k rounds, so O(k n log n) siya Finally, since k is O(m), the final complexity is O(mn log n), which works naman. No need for pqueue, pampasakit lamang yun sa ulo para sa implementation haha (baka sumabog pa ang utak ko lol) also why am I suddenly writing Taglish LOL ANYWAYS, that handles the assignment part of the problem now, we need to quickly construct the subset, haha paano yun though? so, for every color, there is a corresponding opportunity cost (wow, just like in economics, where every decision has a corresponding opportunity cost) o, tapos, i-max-pqueue nalang natin yung <min + max> per color, then repeat the process kn/2 times finally, kung may kulay na wala nang min tickets, assign it a cost of like -infinity or just remove it from the pqueue actually, wait, kailangan nga ba ng pqueue? idts */ // Augment x with indices vvpi xwind; xwind.reserve(n); LI(i, 0, n) { vpi xwindr; xwindr.reserve(m); LI(j, 0, m) { xwindr.pb({x[i][j], j}); } sort(xwindr.begin(), xwindr.end()); xwind.pb(xwindr); } // Representation: pair<opcost :: ll, inds :: pi>, tapos sort it decreasing typedef pair<ll, pi> opcost; vector<opcost> opcosts; // Thanks again MA'AM BAMBIE LI(i, 0, n) { LI(j, 0, k) { int t1 = xwind[i][j].fi, t2 = xwind[i][j - k + m].fi; opcosts.pb({t1 + t2, {i, j}}); } } sort(opcosts.begin(), opcosts.end(), greater<opcost>()); // It's time to be greedy typedef vector<deque<int>> picked_t; picked_t picked; // ! normal_i_ind -> xwind_j_ind (need to convert sorted ind "xwind_j_ind" to normal ind, this should be accessible from xwind naman) vpi num_max; LI(i, 0, n) { deque<int> picked_r; picked.pb(picked_r); num_max.pb({0, i}); } LI(i, 0, k * n) { // Mark these to be done greedily auto [_, ind_pair] = opcosts[i]; // Man, I wished we had auto [_, [i1, i2]] for structured bindings, like in JavaScript :( auto [i1, i2] = ind_pair; bool is_max = i < ((k * n) >> 1); int picked_ind = is_max ? i2 - k + m : i2; // ! lots of math, check this again! picked[i1].push_front(picked_ind); if(is_max) num_max[i1].fi++; ans = ans + (is_max ? (ll)xwind[i1][picked_ind].fi : -(ll)xwind[i1][picked_ind].fi); } // Eyoo, it passes sample test case?? // Allocation time LI(i, 0, k) { // Sort the colors by number of maxes to assign sort(num_max.begin(), num_max.end(), greater<pi>()); LI(j, 0, n >> 1) { // assign maxes int i1 = num_max[j].se; int i2 = picked[i1].back(); int xspace_i2 = xwind[i1][i2].se; talloc[i1][xspace_i2] = i; picked[i1].pop_back(); num_max[j].fi--; } LI(j, n >> 1, n) { // assign mins int i1 = num_max[j].se; int i2 = picked[i1].front(); int xspace_i2 = xwind[i1][i2].se; talloc[i1][xspace_i2] = i; picked[i1].pop_front(); } } allocate_tickets(talloc); return ans; } #ifdef DEBUG int main() { int n, m, k; cin >> n >> m >> k; vvi x; LI(i, 0, n) { vi xr(m, 0); vi tar; INPV(xr); x.pb(xr); ta.pb(tar); } cout << find_maximum(k, x) << "\n"; LI(i, 0, n) { LI(j, 0, m) cout << ta[i][j] << " "; cout << "\n"; } return 0; } #endif
#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...