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

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

int n, m, isLeaf[100005], bit[2][2][100005], X, Y;
string s[100005];
vector<int> G[100005];

int cal(int T, string t) {

  if (t[3] == '&') {
    if (t[4] == 'X')
      return T & X;
    if (t[4] == 'Y')
      return T & Y;
  }

  if (t[3] == '|') {
    if (t[4] == 'X')
      return T | X;
    if (t[4] == 'Y')
      return T | Y;
  }

  if (t[3] == '^') {
    if (t[4] == 'X')
      return T ^ X;
    if (t[4] == 'Y')
      return T ^ Y;
  }
}

void dfs(int x, int px, int T) {

  int nT = 0;

  if (x != 0)
    nT = cal(T, s[x]);

  int flag = 1;

  for (int nx : G[x]) {

    if (nx == px)
      continue;

    flag = 0;

    dfs(nx, x, nT);
  }

  isLeaf[x] = flag;

  bit[X][Y][x] = nT;
}

int get(int I, int x) {
  if (I == 0)
    return bit[0][1][x];
  if (I == 1)
    return bit[1][0][x];
  return bit[1][1][x];
}

int MM[3][3][3][100005];

int minmax(int x, int px, int dep, int I1, int I2, int I3) {

  if (isLeaf[x]) {

    int res = 0;

    res |= get(I1, x);
    res = res << 1;
    res |= get(I2, x);
    res = res << 1;
    res |= get(I3, x);

    return MM[I1][I2][I3][x] = res;
  }

  int res;

  if (dep % 2 == 0)
    res = 0;
  else
    res = 10;

  for (int nx : G[x]) {

    if (nx == px)
      continue;

    if (dep % 2 == 0)
      res = max(res, minmax(nx, x, dep + 1, I1, I2, I3));
    else
      res = min(res, minmax(nx, x, dep + 1, I1, I2, I3));
  }

  return MM[I1][I2][I3][x] = res;
}

signed main() {

  cin >> n >> m;

  for (int i = 1; i < n; i++)
    cin >> s[i];

  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    G[u].push_back(v);
    G[v].push_back(u);
  }

  for (X = 0; X <= 1; X++) {

    for (Y = 0; Y <= 1; Y++) {

      dfs(0, -1, 0);
    }
  }

  minmax(0, -1, 0, 0, 1, 2);
  minmax(0, -1, 0, 0, 2, 1);
  minmax(0, -1, 0, 1, 0, 2);
  minmax(0, -1, 0, 1, 2, 0);
  minmax(0, -1, 0, 2, 0, 1);
  minmax(0, -1, 0, 2, 1, 0);

  for (int i = 0; i < m; i++) {

    cin >> X >> Y;

    int ans = 0;

    int used[3] = {};
    vector<int> pri;

    for (int j = 16; j >= 0; j--) {

      if (((X >> j) & 1) == 0 && (Y >> j & 1) == 1) {

        if (used[0])
          continue;
        used[0] = 1;

        pri.push_back(0);
      }

      if (((X >> j) & 1) == 1 && (Y >> j & 1) == 0) {

        if (used[1])
          continue;
        used[1] = 1;

        pri.push_back(1);
      }

      if (((X >> j) & 1) == 1 && (Y >> j & 1) == 1) {

        if (used[2])
          continue;
        used[2] = 1;

        pri.push_back(2);
      }
    }

    for (int j = 0; j < 3; j++)
      if (used[j] == 0)
        pri.push_back(j);

    int I1 = pri[0], I2 = pri[1], I3 = pri[2];

    for (int j = 0; j < 17; j++) {

      if (((X >> j) & 1) == 0 && (Y >> j & 1) == 1) {
        if (I1 == 0)
          ans |= (MM[I1][I2][I3][0] >> 2 & 1) << j;
        if (I2 == 0)
          ans |= (MM[I1][I2][I3][0] >> 1 & 1) << j;
        if (I3 == 0)
          ans |= (MM[I1][I2][I3][0] >> 0 & 1) << j;
      }

      if (((X >> j) & 1) == 1 && (Y >> j & 1) == 0) {
        if (I1 == 1)
          ans |= (MM[I1][I2][I3][0] >> 2 & 1) << j;
        if (I2 == 1)
          ans |= (MM[I1][I2][I3][0] >> 1 & 1) << j;
        if (I3 == 1)
          ans |= (MM[I1][I2][I3][0] >> 0 & 1) << j;
      }

      if (((X >> j) & 1) == 1 && (Y >> j & 1) == 1) {
        if (I1 == 2)
          ans |= (MM[I1][I2][I3][0] >> 2 & 1) << j;
        if (I2 == 2)
          ans |= (MM[I1][I2][I3][0] >> 1 & 1) << j;
        if (I3 == 2)
          ans |= (MM[I1][I2][I3][0] >> 0 & 1) << j;
      }
    }

    cout << ans << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

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

int n, m, isLeaf[100005], bit[2][2][100005], X, Y;
string s[100005];
vector<int> G[100005];

int cal(int T, string t) {

  if (t[3] == '&') {
    if (t[4] == 'X')
      return T & X;
    if (t[4] == 'Y')
      return T & Y;
  }

  if (t[3] == '|') {
    if (t[4] == 'X')
      return T | X;
    if (t[4] == 'Y')
      return T | Y;
  }

  if (t[3] == '^') {
    if (t[4] == 'X')
      return T ^ X;
    if (t[4] == 'Y')
      return T ^ Y;
  }
}

void dfs(int x, int px, int T) {

  int nT = 0;

  if (x != 0)
    nT = cal(T, s[x]);

  int flag = 1;

  for (int nx : G[x]) {

    if (nx == px)
      continue;

    flag = 0;

    dfs(nx, x, nT);
  }

  isLeaf[x] = flag;

  bit[X][Y][x] = nT;
}

int get(int I, int x) {
  if (I == 0)
    return bit[0][1][x];
  if (I == 1)
    return bit[1][0][x];
  return bit[1][1][x];
}

int MM[3][3][3][100005];

int minmax(int x, int px, int dep, int I1, int I2, int I3) {

  if (isLeaf[x]) {

    int res = 0;

    res |= get(I1, x);
    res = res << 1;
    res |= get(I2, x);
    res = res << 1;
    res |= get(I3, x);

    return MM[I1][I2][I3][x] = res;
  }

  int res;

  if (dep % 2 == 0)
    res = 0;
  else
    res = 10;

  for (int nx : G[x]) {

    if (nx == px)
      continue;

    if (dep % 2 == 0)
      res = max(res, minmax(nx, x, dep + 1, I1, I2, I3));
    else
      res = min(res, minmax(nx, x, dep + 1, I1, I2, I3));
  }

  return MM[I1][I2][I3][x] = res;
}

signed main() {

  cin >> n >> m;

  for (int i = 1; i < n; i++)
    cin >> s[i];

  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    G[u].push_back(v);
    G[v].push_back(u);
  }

  for (X = 0; X <= 1; X++) {

    for (Y = 0; Y <= 1; Y++) {

      dfs(0, -1, 0);
    }
  }

  minmax(0, -1, 0, 0, 1, 2);
  minmax(0, -1, 0, 0, 2, 1);
  minmax(0, -1, 0, 1, 0, 2);
  minmax(0, -1, 0, 1, 2, 0);
  minmax(0, -1, 0, 2, 0, 1);
  minmax(0, -1, 0, 2, 1, 0);

  for (int i = 0; i < m; i++) {

    cin >> X >> Y;

    int ans = 0;

    for (int I1 = 0; I1 <= 2; I1++) {

      for (int I2 = 0; I2 <= 2; I2++) {

        for (int I3 = 0; I3 <= 2; I3++) {

          if (I1 == I2 || I2 == I3)
            continue;

          int val = 0;

          for (int j = 0; j < 17; j++) {

            if ((X >> j & 1) == 0 && (Y >> j & 1) == 1) {
              if (I1 == 0)
                val += (MM[I1][I2][I3][0] >> 2 & 1) << j;
              if (I2 == 0)
                val += (MM[I1][I2][I3][0] >> 1 & 1) << j;
              if (I3 == 0)
                val += (MM[I1][I2][I3][0] >> 0 & 1) << j;
            }

            if ((X >> j & 1) == 1 && (Y >> j & 1) == 0) {
              if (I1 == 1)
                val += (MM[I1][I2][I3][0] >> 2 & 1) << j;
              if (I2 == 1)
                val += (MM[I1][I2][I3][0] >> 1 & 1) << j;
              if (I3 == 1)
                val += (MM[I1][I2][I3][0] >> 0 & 1) << j;
            }

            if ((X >> j & 1) == 1 && (Y >> j & 1) == 1) {
              if (I1 == 2)
                val += (MM[I1][I2][I3][0] >> 2 & 1) << j;
              if (I2 == 2)
                val += (MM[I1][I2][I3][0] >> 1 & 1) << j;
              if (I3 == 2)
                val += (MM[I1][I2][I3][0] >> 0 & 1) << j;
            }
          }

          ans = max(ans, val);
        }
      }
    }

    cout << ans << endl;
  }

  return 0;
}