Submission #1270823

#TimeUsernameProblemLanguageResultExecution timeMemory
1270823strange420선물 (IOI25_souvenirs)C++20
100 / 100
12 ms416 KiB
#include "souvenirs.h"
#include <utility>
#include <vector>
#include <iostream>
#include <algorithm>

std::pair<std::vector<int>, long long> specialTransaction(long long M, std::vector<int> &cnt, std::vector<long long> &price) {
  std::pair<std::vector<int>, long long> res = transaction(M);
  for (auto x: res.first) {
    cnt[x]++;
  }

  std::vector<int> asd;
  for (int x: res.first) {
    if (price[x]) { res.second += price[x]; }
    else { asd.push_back(x); }
  }

  if (asd.size() == 1) {
    price[asd[0]] = M - res.second;
    res.second = M;
    asd.clear();
  }

  return std::pair(asd, M - res.second);
}

void simplify(std::vector<std::pair<std::vector<int>, long long>> &equations, std::vector<long long> &price) {
  while(true) {
    std::vector<std::pair<std::vector<int>, long long>> equations2;
    for (auto pp: equations) {
      if (pp.first.size() < 1) continue;
      if (pp.first.size() == 1) {
        price[pp.first[0]] = pp.second;
        continue;
      }

      int zeros = 0, ind = -1;
      long long part = 0;
      std::vector<int> asd;
      for (int x: pp.first) {
        if (!price[x]) {
          zeros++;
          ind = x;
          asd.push_back(x);
        } else {
          part += price[x];
        }
      }

      if (zeros == 1) {
        price[ind] = pp.second - part;
      } else {
        if (pp.second - part == 0) continue;
        equations2.push_back(std::pair(asd, pp.second - part));
      }
    }
    equations = equations2;

    bool flag = false;
    for (auto pp: equations) {
      for (int x: pp.first) {
        if (price[x]) {
          flag = true;
        }
      }
    }
    if (!flag) {
      break;
    }
  }
}

void resolve(long long current_price, int target, std::vector<long long> &price, std::vector<int> &cnt, std::vector<std::pair<std::vector<int>, long long>> &equations) {
  while (price[target] == 0) {
    std::pair<std::vector<int>, long long> res = specialTransaction(current_price, cnt, price);
    simplify(equations, price);

    if (res.first.size() == 0) {
      int i = target; for (; !price[i]; i--) {}
      if (price[i]-1 >= current_price) break;
      current_price = price[i] - 1;
    } else {
      equations.push_back(res);
      current_price = res.second/res.first.size();
    }
  }
}

void resolve_all(std::vector<std::pair<std::vector<int>, long long>> &equations, std::vector<long long> &price, std::vector<int> &cnt) {
  while(equations.size()) {
    simplify(equations, price);
    int x = equations.size()-1;
    std::vector<int> num = equations[x].first;
    long long sum = equations[x].second, smallest = sum/num.size();
    for (int i=num[0]; i<=num[num.size()-1]; i++) {
      if (!price[i]) continue;
      smallest = std::min(smallest, price[i]-1);
    }
    resolve(smallest, num[num.size()-1], price, cnt, equations);
  }
}

void solve(int N, long long P0) {
  // Subtask 6
  std::vector<int> cnt(N, 0);
  std::vector<long long> price(N, 0); price[0] = P0;
  std::vector<std::pair<std::vector<int>, long long>> equations;

  int lo = 1, hi = N-1;
  while (lo <= hi) {
    resolve(price[lo-1]-1, hi, price, cnt, equations);
    resolve_all(equations, price, cnt);

    while(price[lo] != 0) lo++;
    while(price[hi] != 0) hi--;
  }

  for (int i=0; i<N; i++) {
    while (cnt[i] < i) {
      transaction(price[i]);
      cnt[i]++;
    }
  }
}

void buy_souvenirs(int N, long long P0) {
  if (N == 2) {
    // Subtask 1
    transaction(P0 - 1);
  } else if (P0 == N) {
    // Subtask 2
    for (long long i = N-1, k = 1; i>0; i--, k++) {
      for (int j = 0; j < k; j++) {
        transaction(i);
      }
    }
  } else if (N == 3) {
    // Subtask 4
    std::pair<std::vector<int>, long long> res = transaction(P0-1);
    long long price = P0-1-res.second;
    if (res.first.size() == 1) {
      transaction(price-1);
      transaction(price-1);
    } else {
      long long special = price / 2;
      transaction(special);
    }
  } else {
    solve(N, P0);
  }
}
#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...