Problem p00540 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>
using namespace std;

#define st first
#define nd second
#define mp make_pair
#define space << " " <<
#define END << endl
#define pb push_back
#define fo(i, n) for (int i = 0; i < n; ++i)
#define ff(i, n) for (int i = 1; i < n; ++i)

typedef vector<int> vi;
typedef pair<int, int> pii;
typedef pair<int, pii> pi;
typedef long long ll;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef pair<ll, pll> pl;
typedef vector<pil> vil;

const int N = 5000;
const int INF = 10000000;

int s[100500];
vector<int> board[INF], su;
int n, m;
int parent[INF];
int dp[INF][3];
bool ok[INF][3];
int root;

void init() {
  sort(su.begin(), su.end());
  deque<int> de;
  for (int x = 1; x <= n; ++x)
    de.push_back(x);
  int l = n + 1;
  while (de.size() != 1) {
    fo(i, 3) {
      int u = de.front();
      de.pop_front();
      parent[u] = l;
    }
    de.push_back(l);
    l++;
  }
  root = de.front();
  for (int x = 1; x < root; ++x)
    board[parent[x]].push_back(x);
}

int dfs(int node, int num, int cost) {
  if (ok[node][num])
    return dp[node][num];
  ok[node][num] = 1;
  if (node <= n) {
    if (s[node] && cost <= s[node] && !num)
      return dp[node][num] = INF;
    else if (s[node] && cost > s[node] && num)
      return dp[node][num] = INF;
    else if (s[node] && cost <= s[node] && num)
      return dp[node][num] = num;
    else if (s[node] && cost > s[node] && !num)
      return dp[node][num] = num;
    else
      return dp[node][num] = num;
  } else {
    int ans = INF;
    for (int x = 0; x < 3; ++x)
      ans = min(ans, dfs(board[node][x], 1 - num, cost) +
                         dfs(board[node][(x + 1) % 3], num, cost) +
                         dfs(board[node][(x + 2) % 3], num, cost));
    ans = min(ans, dfs(board[node][0], num, cost) +
                       dfs(board[node][1], num, cost) +
                       dfs(board[node][2], num, cost));
    return dp[node][num] = ans;
  }
}

bool check(int u) {
  int k = 0;
  for (int x = 0; x < su.size(); ++x)
    if (su[x] >= u)
      k++;
  for (int x = 0; x <= root; ++x)
    for (int y = 0; y < 2; ++y)
      dp[x][y] = ok[x][y] = 0;
  int kk = dfs(root, 1, u);
  if (kk > k)
    return 0;
  else
    return 1;
}

int work() {
  init();
  int l = 0;
  int r = n - 1;
  while (r - l > 1) {
    int mid = (r + l) / 2;
    if (check(su[mid]))
      l = mid;
    else
      r = mid;
  }
  if (check(su[r]))
    return su[r];
  else
    return su[l];
}

int main() {
  // freopen("test.txt","r",stdin);
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int u, v;
    cin >> u >> v;
    s[v] = u;
    su.pb(u);
  }
  for (int i = 0; i < n - m; ++i) {
    int u;
    cin >> u;
    su.pb(u);
  }
  cout << work() << endl;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define st first
#define nd second
#define mp make_pair
#define space << " " <<
#define END << endl
#define pb push_back
#define fo(i, n) for (int i = 0; i < n; ++i)
#define ff(i, n) for (int i = 1; i < n; ++i)

typedef vector<int> vi;
typedef pair<int, int> pii;
typedef pair<int, pii> pi;
typedef long long ll;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef pair<ll, pll> pl;
typedef vector<pil> vil;

const int N = 5050;
const int INF = 10000000;

int s[N * N];
vector<int> board[N * N], su;
int n, m;
int parent[N * N];
int dp[N * N][3];
bool ok[N * N][3];
int root;

void init() {
  sort(su.begin(), su.end());
  deque<int> de;
  for (int x = 1; x <= n; ++x)
    de.push_back(x);
  int l = n + 1;
  while (de.size() != 1) {
    fo(i, 3) {
      int u = de.front();
      de.pop_front();
      parent[u] = l;
    }
    de.push_back(l);
    l++;
  }
  root = de.front();
  for (int x = 1; x < root; ++x)
    board[parent[x]].push_back(x);
}

int dfs(int node, int num, int cost) {
  if (ok[node][num])
    return dp[node][num];
  ok[node][num] = 1;
  if (node <= n) {
    if (s[node] && cost <= s[node] && !num)
      return dp[node][num] = INF;
    else if (s[node] && cost > s[node] && num)
      return dp[node][num] = INF;
    else if (s[node] && cost <= s[node] && num)
      return dp[node][num] = num;
    else if (s[node] && cost > s[node] && !num)
      return dp[node][num] = num;
    else
      return dp[node][num] = num;
  } else {
    int ans = INF;
    for (int x = 0; x < 3; ++x)
      ans = min(ans, dfs(board[node][x], 1 - num, cost) +
                         dfs(board[node][(x + 1) % 3], num, cost) +
                         dfs(board[node][(x + 2) % 3], num, cost));
    ans = min(ans, dfs(board[node][0], num, cost) +
                       dfs(board[node][1], num, cost) +
                       dfs(board[node][2], num, cost));
    return dp[node][num] = ans;
  }
}

bool check(int u) {
  int k = 0;
  for (int x = 0; x < su.size(); ++x)
    if (su[x] >= u)
      k++;
  for (int x = 0; x <= root; ++x)
    for (int y = 0; y < 2; ++y)
      dp[x][y] = ok[x][y] = 0;
  int kk = dfs(root, 1, u);
  if (kk > k)
    return 0;
  else
    return 1;
}

int work() {
  init();
  int l = 0;
  int r = n - 1;
  while (r - l > 1) {
    int mid = (r + l) / 2;
    if (check(su[mid]))
      l = mid;
    else
      r = mid;
  }
  if (check(su[r]))
    return su[r];
  else
    return su[l];
}

int main() {
  // freopen("test.txt","r",stdin);
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int u, v;
    cin >> u >> v;
    s[v] = u;
    su.pb(u);
  }
  for (int i = 0; i < n - m; ++i) {
    int u;
    cin >> u;
    su.pb(u);
  }
  cout << work() << endl;
}