WA/TLE 17 分求助
查看原帖
WA/TLE 17 分求助
726139
残阳如血楼主2024/4/27 14:02
#include <set>
#include <queue>
#include <iostream>
const int N = 1e5 + 10;

bool son[N];
// 是否有孩子
std::set<std::pair<int, int>> node;
// first:dfn second:编号,功能类似优先队列
int n, q, s, cnt, fa[N], dfn[N], f[N][20];

void dfs(int u) { // 获得 dfs 序
  if (!son[u]) { // 叶子节点
    node.insert({dfn[u] = ++cnt, u});
    return ;
  }
  for (auto v : son[u]) dfs(v);
  node.insert({dfn[u] = ++cnt, u});
}

void init() { // 类似 LCA 初始化
  for (int j = 0; j < 20; ++j)
    for (int i = 1; i <= n; ++i) {
      if (!j) f[i][j] = fa[i];
      else f[i][j] = f[f[i][j - 1]][j - 1];
    }
}

int main() {
  std::cin.tie(0)->sync_with_stdio(0);
  std::cin >> n >> q;
  for (int i = 1, x; i <= n; ++i)
    std::cin >> x, fa[i] = x, son[x] = true;
  for (int i = 1; i <= n; ++i)
    if (!fa[i]) { s = i; break; } // fa[i] = 0 的就是根节点
  dfs(s), init(); // 初始化
  for (int opt, num; q; --q) {
    std::cin >> opt >> num;
    if (opt == 1) {
      for (int i = 1; i < num; ++i) node.erase(node.begin());
      std::cout << node.begin()->second << '\n', node.erase(node.begin());
    } else {
      // 找最远的有球的祖先
      int t = num, len = 0;
      for (int i = 19; ~i; --i) {
        if (!f[t][i] || node.find({dfn[f[t][i]], f[t][i]}) != node.end()) continue; // 跳过头了
        t = f[t][i], len += 1 << i;
      }
      node.insert({dfn[t], t}); // 链的最上端空了
      std::cout << len << '\n';
    }
  }
  std::cout.flush();
  return 0;
}
2024/4/27 14:02
加载中...