Problem p01816 (C++) — buggy submission, verdict: Time Limit Exceeded

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

struct Edge {
  int from;
  int to;
  int id;
  long long int cost;
};

void dfs(const int now, const int from, const vector<vector<int>> &edges,
         const vector<int> &types, vector<int> &nums) {
  for (auto e : edges[now]) {
    if (e == from)
      continue;
    {
      const int nt = types[e];
      if (nt == 0) {
        nums[e] = nums[now] & 0b110;
      } else if (nt == 1) {
        nums[e] = nums[now] & 0b101;
      } else if (nt == 2) {
        nums[e] = nums[now] | 0b110;
      } else if (nt == 3) {
        nums[e] = nums[now] | 0b101;
      } else if (nt == 4) {
        nums[e] = nums[now] ^ 0b110;
      } else if (nt == 5) {
        nums[e] = nums[now] ^ 0b101;
      }
    }
    dfs(e, now, edges, types, nums);
  }
}

int dfs2(const int now, const int from, const vector<vector<int>> &edges,
         const vector<int> &types, bool is_a, vector<int> &perms) {

  if (edges[now].size() == 1 && from != -1)
    return perms[types[now]];
  int ans;
  if (is_a) {
    ans = -1;
  } else {
    ans = 100;
  }

  for (auto e : edges[now]) {
    if (e == from)
      continue;
    if (is_a) {
      ans = max(ans, dfs2(e, now, edges, types, !is_a, perms));
    } else {
      ans = min(ans, dfs2(e, now, edges, types, !is_a, perms));
    }
  }
  return ans;
}

int main() {
  int N, M;
  cin >> N >> M;

  map<vector<int>, int> ans_mp;

  vector<int> types(N, -1);
  vector<string> name_sts{
      "T=T&X", "T=T&Y", "T=T|X", "T=T|Y", "T=T^X", "T=T^Y",
  };

  for (int i = 1; i < N; ++i) {
    string st;
    cin >> st;
    types[i] = find(name_sts.begin(), name_sts.end(), st) - name_sts.begin();
  }

  vector<vector<int>> edges(N);
  for (int i = 0; i < N - 1; ++i) {
    int a, b;
    cin >> a >> b;
    edges[a].push_back(b);
    edges[b].push_back(a);
  }
  vector<int> nums(N);
  dfs(0, -1, edges, types, nums);

  /*vector<int>perms(8);
  iota(perms.begin(),perms.end(),0);
  do {
          bool ok=true;
          for (int i = 1; i < 8; ++i) {
                  for (int j = 1; j < 8; ++j) {
                          if ((i|j) == j) {
                                  if (perms[i] > perms[j]) {
                                          ok = false;
                                  }
                          }
                  }
          }
          if(perms[0]<perms[2])
          if(!ok)continue;
          auto num = dfs2(0, -1, edges, nums, true, perms);
          ans_mp[perms] =find(perms.begin(),perms.end(),num)-perms.begin();
  } while (next_permutation(perms.begin() + 1, perms.end() - 1));
*/

  while (M--) {
    int X, Y;
    cin >> X >> Y;
    int onlyX = ((X | Y) ^ Y);
    int onlyY = ((X | Y) ^ X);
    vector<pair<int, int>> ps;
    vector<int> anums{
        0, onlyY, onlyX, onlyX | onlyY, X & Y, Y, X, X | Y,
    };
    for (int i = 0; i < 8; ++i) {
      ps.emplace_back(anums[i], i);
    }
    sort(ps.begin(), ps.end());
    vector<int> perms(8);
    for (int i = 0; i < 8; ++i) {
      perms[ps[i].second] = i;
    }
    if (ans_mp.find(perms) == ans_mp.end()) {
      auto num = dfs2(0, -1, edges, nums, true, perms);
      ans_mp[perms] = find(perms.begin(), perms.end(), num) - perms.begin();
    }
    int ans_id = ans_mp[perms];
    int ans = anums[ans_id];
    cout << anums[ans_id] << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

struct Edge {
  int from;
  int to;
  int id;
  long long int cost;
};

void dfs(const int now, const int from, const vector<vector<int>> &edges,
         const vector<int> &types, vector<int> &nums) {
  for (auto e : edges[now]) {
    if (e == from)
      continue;
    {
      const int nt = types[e];
      if (nt == 0) {
        nums[e] = nums[now] & 0b110;

      } else if (nt == 1) {
        nums[e] = nums[now] & 0b101;

      } else if (nt == 2) {
        nums[e] = nums[now] | 0b110;
      } else if (nt == 3) {
        nums[e] = nums[now] | 0b101;
      } else if (nt == 4) {
        nums[e] = nums[now] ^ 0b110;
      } else if (nt == 5) {
        nums[e] = nums[now] ^ 0b101;
      }
    }
    dfs(e, now, edges, types, nums);
  }
}

int dfs2(const int now, const int from, const vector<vector<int>> &edges,
         const vector<int> types, bool is_a, vector<int> &perms) {

  if (edges[now].size() == 1)
    return perms[types[now]];
  int ans;
  if (is_a) {
    ans = -1;
  } else {
    ans = 100;
  }

  for (auto e : edges[now]) {
    if (e == from)
      continue;
    if (is_a) {
      ans = max(ans, dfs2(e, now, edges, types, !is_a, perms));
    } else {
      ans = min(ans, dfs2(e, now, edges, types, !is_a, perms));
    }
  }
  return ans;
}

int main() {
  int N, M;
  cin >> N >> M;

  map<vector<int>, int> ans_mp;

  vector<int> types(N, -1);
  vector<string> name_sts{
      "T=T&X", "T=T&Y", "T=T|X", "T=T|Y", "T=T^X", "T=T^Y",
  };

  for (int i = 1; i < N; ++i) {
    string st;
    cin >> st;
    types[i] = find(name_sts.begin(), name_sts.end(), st) - name_sts.begin();
  }

  vector<vector<int>> edges(N);
  for (int i = 0; i < N - 1; ++i) {
    int a, b;
    cin >> a >> b;
    edges[a].push_back(b);
    edges[b].push_back(a);
  }
  vector<int> nums(N);
  dfs(0, -1, edges, types, nums);

  /*vector<int>perms(8);
  iota(perms.begin(),perms.end(),0);
  do {
          bool ok=true;
          for (int i = 1; i < 8; ++i) {
                  for (int j = 1; j < 8; ++j) {
                          if ((i|j) == j) {
                                  if (perms[i] > perms[j]) {
                                          ok = false;
                                  }
                          }
                  }
          }
          if(perms[0]<perms[2])
          if(!ok)continue;
          auto num = dfs2(0, -1, edges, nums, true, perms);
          ans_mp[perms] =find(perms.begin(),perms.end(),num)-perms.begin();
  } while (next_permutation(perms.begin() + 1, perms.end() - 1));
*/

  while (M--) {
    if (M == 99000)
      break;
    int X, Y;
    cin >> X >> Y;
    int onlyX = ((X | Y) ^ Y);
    int onlyY = ((X | Y) ^ X);
    vector<pair<int, int>> ps;
    vector<int> anums{
        0, onlyY, onlyX, onlyX | onlyY, X & Y, Y, X, X | Y,
    };
    for (int i = 0; i < 8; ++i) {
      ps.emplace_back(anums[i], i);
    }
    sort(ps.begin(), ps.end());
    vector<int> perms(8);
    for (int i = 0; i < 8; ++i) {
      perms[ps[i].second] = i;
    }
    if (ans_mp.find(perms) == ans_mp.end()) {
      auto num = dfs2(0, -1, edges, nums, true, perms);
      ans_mp[perms] = find(perms.begin(), perms.end(), num) - perms.begin();
    }
    int ans_id = ans_mp[perms];
    int ans = anums[ans_id];
    cout << anums[ans_id] << endl;
  }
  return 0;
}