Submission #1342049

#TimeUsernameProblemLanguageResultExecution timeMemory
1342049mehrzadSouvenirs (IOI25_souvenirs)C++17
21 / 100
12 ms352 KiB
#include "souvenirs.h"
  #include <bits/stdc++.h>

  using namespace std;

  void buy_souvenirs(int N, long long P0) {
      // price[0] is known, other prices will be discovered
      vector<long long> price(N);
      price[0] = P0;

      // need[i] = how many copies of type i we still have to obtain
      vector<int> need(N, 0);
      for (int i = 0; i < N; ++i) need[i] = i;   // type 0 should stay at 0

      /* --------------------------------------------------------------
         1.  Determine the prices for indices 1 .. N-2.
             For each i we issue a "probe" transaction with
                 M = price[i-1] - 2   (always >= cheapest price)
             The transaction will buy either type i (if the gap is 2)
             or some later type (if the gap is 1).  From the first bought
             type we can infer the exact gap, thus price[i].
             While probing we also count the souvenirs that were bought.
         -------------------------------------------------------------- */
      for (int i = 1; i <= N - 2; ++i) {
          long long M = price[i - 1] - 2;          // safe and valid
          auto res = transaction(M);
          const vector<int> &L = res.first;

          // we have bought one souvenir for each type in L
          for (int t : L) {
              // each purchase should still be needed
              --need[t];
          }

          // decide the gap (1 or 2) and fix price[i]
          int gap = 1;                              // default: gap = 1
          if (!L.empty() && L[0] == i) gap = 2;    // bought i -> gap = 2
          price[i] = price[i - 1] - gap;

          // buy the remaining copies of type i (if any)
          int remaining = need[i];                  // may be zero or positive
          for (int k = 0; k < remaining; ++k) {
              long long M2 = price[i];              // exactly price[i]; buys only i
              auto res2 = transaction(M2);
              for (int t : res2.first) {
                  --need[t];
              }
          }
          // after this, need[i] should be zero
      }

      /* --------------------------------------------------------------
         2.  Finally buy the remaining copies of the cheapest type (N-1).
             We already know price[N-2]; set
                 M = price[N-2] - 1
             This value is guaranteed to be >= price[N-1] and < price[N-2],
             so each transaction buys exactly one souvenir of type N-1.
         -------------------------------------------------------------- */
      long long M_last = price[N - 2] - 1;          // works also for N == 2
      while (need[N - 1] > 0) {
          auto res = transaction(M_last);
          for (int t : res.first) {
              --need[t];
          }
      }
      // At this point all need[t] should be zero.
  }
  
#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...