dsu on tree TLE #54 求助
查看原帖
dsu on tree TLE #54 求助
648550
eoinlee楼主2024/11/24 22:29
#pragma GCC optimize("O2,unroll-loops")
#include <bits/stdc++.h>

using u32 = unsigned int;
using PII = std::pair<int, int>;

const int MAX_N = 500'005;

int N, M;
char ch[MAX_N];
std::vector<std::vector<int>> gg;

int fa[MAX_N], dep[MAX_N], size[MAX_N], pref[MAX_N];
int dfn[MAX_N], ver[MAX_N], ts;

void DFS1(int u) {
  size[u] = 1;
  dep[u] = dep[fa[u]] + 1;
  dfn[u] = ++ts, ver[ts] = u;

  for (int v : gg[u]) {
    DFS1(v);
    size[u] += size[v];
    if (size[v] > size[pref[u]]) pref[u] = v;
  }
}

bool ans[MAX_N];
std::vector<std::vector<PII>> qd;
u32 cnt[MAX_N];

void upd(int u) { cnt[dep[u]] ^= 1U << (ch[u] - 'a'); }

void DFS2(int u, bool psv) {
  for (int v : gg[u])
    if (v != pref[u])
      DFS2(v, false);

  if (pref[u]) DFS2(pref[u], true);

  for (int v : gg[u])
    if (v != pref[u])
      for (int i = dfn[v]; i <= dfn[v] + size[v] - 1; ++i)
        upd(ver[i]);

  upd(u);
  for (auto [d, id] : qd[u]) ans[id] = std::popcount(cnt[d]) <= 1;

  if (!psv)
    for (int i = dfn[u]; i <= dfn[u] + size[u] - 1; ++i)
      upd(ver[i]);
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);

  std::cin >> N >> M;
  gg.resize(N + 1), qd.resize(N + 1);

  for (int i = 2; i <= N; ++i) std::cin >> fa[i], gg[fa[i]].push_back(i);
  for (int i = 1; i <= N; ++i) std::cin >> ch[i];

  DFS1(1);

  for (int i = 1, rt, dep; i <= M; ++i)
    std::cin >> rt >> dep, qd[rt].emplace_back(dep, i);

  DFS2(1, true);

  for (int i = 1; i <= M; ++i) std::cout << (ans[i] ? "Yes" : "No") << '\n';
  return 0;
}
2024/11/24 22:29
加载中...