제출 #1331010

#제출 시각아이디문제언어결과실행 시간메모리
1331010rainmarSouvenirs (IOI25_souvenirs)C++20
7 / 100
1068 ms1164 KiB
#include "souvenirs.h"
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define f first
#define s second

#define all(x) x.begin(),x.end()

vector<int> cnt;
unordered_map<int,bool> asked;
unordered_map<int,pair<vector<int>, ll>> result;

pair<vector<int>, ll> wrapper(ll S) {

  if(asked[S] == true) {
    return result[S];
  } else {
    asked[S] = true;
    result[S] = transaction(S);
    for(auto e : result[S].first) cnt[e]++;
    return result[S];
  }

}

void buy_souvenirs(int N, long long P0) {

  asked.clear();
  result.clear();
  cnt.clear();

  ofstream out("output.txt");

  vector<pair<ll,vector<int>>> que;
  //try to get the smallest

  cnt = vector<int>(N,0);
  vector<ll> know(N+1,-1);
  know[0] = P0;

  ll s = P0 - 1;
  while(true) {
    out << "callll 1 for " << s << endl;
    pair<vector<int>, ll> res = wrapper(s);

    ll sum = s - res.second;

    if(res.first.size() == 1) {
      
      know[res.first[0]] = sum;
      out << "defaulted " << res.first[0] << " is " << sum << " after having called " << s << endl;
      s = sum - 1;
      if(res.first[0] == N-1) break;

    } else {
      s = (sum + res.f.size() - 1)/res.f.size();
      que.push_back({sum, res.first});

    }
  }

  while(que.size() > 0) {
    bool changed = false;

    for(int w = 0; w < (int)que.size(); w++) {
      pair<ll,vector<int>> t = que[w];
      for(int i = t.s.size()-1; i>=0; i--) {
        if(know[t.s[i]]!=-1) {
          t.f -= know[t.s[i]];
          swap(t.s[i], t.s[t.s.size()-1]);
          t.s.pop_back();
          //t.s.erase(t.s.begin()+i);
        }
      }
      que[w] = t;
      if(que[w].s.size() == 1) {
        know[que[w].s[0]] = que[w].f;

        out << "added " << que[w].s[0] << " as " << que[w].f << "\n";
        changed = true;
        
        /*
        if(que[w].s[0] != N-1 and know[que[w].s[0]+1] == -1) {
          out << "callll 2" << endl;
          pair<vector<int>, ll> res = wrapper(que[w].f-1);
          ll sum = (que[w].f-1) - res.second;
          que.push_back({sum, res.first});
          break;
        }
        */

        swap(que[w], que[que.size()-1]);
        que.pop_back();
        w--;

      } else if(que[w].s.size() == 0) {
        swap(que[w], que[que.size()-1]);
        que.pop_back();
        w--;
      }
    }
    
    bool dif = false;
    for(int i = N-2; i >= 0; i--) {
      //find first that has a one we know before it.
      if(know[i+1] == -1 and know[i] != -1) {
        pair<vector<int>, ll> res = wrapper(know[i]-1);
        ll sum = (know[i]-1) - res.second;

        /*
        for(int j = res.first.size()-1; j>= 0; j--) {
          if(know[res.first[j]] != -1) {
            sum -= know[res.first[j]];
            res.first.erase(res.first.begin()+j);
          }
        }
          */

        dif = true;
        que.push_back({sum, res.first});
        break;
      }
    }

    if(dif) continue;
    sort(all(que));

    pair<ll,vector<int>> t;

    if(que.size() == 0) break;

    t = que[0];

    s = (t.f + t.s.size() - 1)/t.s.size();

    out << "callll 3" << endl;
    pair<vector<int>, ll> res = wrapper(s);
    ll sum = s - res.second;
  
    que.push_back({sum, res.first});
  }

  for(int i = 0; i < N; i++) out << know[i] << " ";
  out << endl;

  for(int i = 0; i < N; i++) {
    out << "calllll 4" << endl;
    while(cnt[i] < i) {transaction(know[i]); cnt[i]++;
      out << "added " << i << endl;
    }
  }
  
  out.flush();
  out.close();

  return;
}
#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...