답안 #375307

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
375307 2021-03-09T07:14:18 Z Mamnoon_Siam Swap (BOI16_swap) C++17
0 / 100
19 ms 28524 KB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ii = pair<int, int>;
using vi = vector<int>;
#define all(v) begin(v), end(v)
#define sz(v) (int)(v).size()
#define fi first
#define se second

const int N = 4e5 + 3;

map<int, vi> dp[N];
int a[N], n, nn;
vi todo[N];

vi merge(vi& p, vi& q, int x) {
  vi r; r.reserve(sz(p)+sz(q)+1);
  r.emplace_back(x);
  int pw = 1;
  int i = 0, j = 0;
  while(i < sz(p) or j < sz(q)) {
    r.insert(r.end(), p.begin()+i, p.begin()+min(sz(p), i+pw));
    r.insert(r.end(), q.begin()+j, q.begin()+min(sz(q), j+pw));
    i = min(i+pw, sz(p));
    j = min(j+pw, sz(q));
    pw *= 2;
  }
  return r;
}

int main(int argc, char* argv[]) {
  cin.sync_with_stdio(0); cin.tie(0);
  cin.exceptions(cin.failbit);
#ifdef LOCAL
  freopen("in", "r", stdin);
#endif
  cin >> n;
  nn = 1;
  while(nn-1 < n) nn *= 2;
  nn--;
  nn = n;
  for(int i = 1; i <= n; ++i)
    cin >> a[i];
  for(int i = n+1; i <= nn; ++i)
    a[i] = n+1;
  for(int i:{1,2,3})
    if(i <= nn) todo[1].emplace_back(a[i]);
  sort(all(todo[1]));
  todo[1].erase(unique(all(todo[1])), todo[1].end());
  for(int i = 2; i <= nn; ++i) {
    for(int j:{i,2*i,2*i+1})
      if(j <= nn) todo[i].emplace_back(a[j]);
    int u = i;
    while(u != 1) {
      if(u & 1) {
        todo[i].emplace_back(a[u^1]);
      }
      todo[i].emplace_back(a[u>>1]);
      u >>= 1;
    }
    sort(all(todo[i]));
    todo[i].erase(unique(all(todo[i])), todo[i].end());
  }
  for(int i = nn/2+1; i <= nn; ++i) {
    for(int x : todo[i])
      dp[i][x] = {x};
  }
  for(int u = nn/2; u >= 1; --u) {
    for(int k : todo[u]) {
      vi& ret = dp[u][k];
      { // don't use any edge
        vi& l = dp[2*u][a[2*u]];
        vi& r = dp[2*u+1][a[2*u+1]];
        ret = merge(l, r, k);
      }
      { // use only left edge
        vi& l = dp[2*u][k];
        vi& r = dp[2*u+1][a[2*u+1]];
        vi tmp = merge(l, r, a[2*u]);
        ret = min(ret, tmp);
      }
      { // use only right edge
        vi& l = dp[2*u][a[2*u]];
        vi& r = dp[2*u+1][k];
        vi tmp = merge(l, r, a[2*u+1]);
        ret = min(ret, tmp);
      }
      { // use both edges
        vi& l = dp[2*u][k];
        vi& r = dp[2*u+1][a[2*u]];
        vi tmp = merge(l, r, a[2*u+1]);
        ret = min(ret, tmp);
      }
    }
    dp[2*u].clear();
    dp[2*u+1].clear();
  }
  vi ans = dp[1][a[1]];
  for(int i = 0; i < n; ++i)
    cout << ans[i] << ' ';
  cout << endl;
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 19 ms 28524 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 19 ms 28524 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 19 ms 28524 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 19 ms 28524 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 19 ms 28524 KB Output isn't correct
2 Halted 0 ms 0 KB -