Atcoder Beginner Round #274 C题 Ameba 题解

\(\texttt{diff: }\color{gray}{315}\)

题意:给定一颗二叉树,问 \(1\) 号节点是 \(i\) 号节点的多少代祖先,\(i\)\(1\sim 2n + 1\) 中的所有整数。

题解:

因为这道题的难度只有 \(315\),所以一定是使用很简单的方法,所以用非常简单的树剖的树上差分写。

由于 \(1\) 号节点是根节点,所以问 \(1\)\(i\) 的多少代祖先就是问 \(1\sim i\) 的距离。

那么就可以在 \(O(n\log n)\) 的时间里求出答案了。

Tips:

树剖需要建双向边。

比如说建边部分:

// 随便举了一个栗子
void add(int a)
{
  z[a].push_back(i << 1);
  z[i << 1].push_back(a);
    // a<<1|1 同理
}

代码:

#include <bits/stdc++.h>

using namespace std;

int n, m;
const int N = 9e5 + 10;
int a[N];
vector <int> z[N];
int dfs_order[N], rk[N], cnt, top[N], len[N], fa[N], sz[N], dep[N], son[N];
void dfs1(int now, int fa = -1)
{
  if (now == 9)
  {
    cerr << "now 'now' = 9.\n";
    cerr << fa << ' ' << ::fa[now] << '\n';
  }
  dep[now] = dep[::fa[now]] + 1;
  sz[now] = 1;
  for (auto &u : z[now])
  {
    if (u == fa)
      continue ;
    ::fa[u] = now;
    dfs1(u, now);
    sz[now] += sz[u];
    if (sz[u] > sz[son[now]])
      son[now] = u;
  }
}

void dfs2(int now, int h, int fa = -1)
{
  cnt ++;
  dfs_order[cnt] = now;
  rk[now] = cnt;
  top[now] = h;
  len[h] ++;
  int p = -1;
  for (auto &u : z[now])
  {
    if (u == fa)
      continue ;
    if (p == -1)
      p = u;
    else if (sz[u] > sz[p])
      p = u;
  }
  if (p == -1)
    return ;
  dfs2(p, h, now);
  for (auto &u : z[now])
    if (p != u && u != fa)
      dfs2(u, u, now);
}

int lca(int x, int y)
{
  while (top[x] != top[y])
  {
    if (dep[top[x]] < dep[top[y]])
      swap (x, y);
    x = fa[top[x]];
  }
  if (dep[x] < dep[y])
    return x;
  return y;
}

int qdis(int u, int v)
{
  return dep[u] + dep[v] - 2 * dep[lca(u, v)];
}

signed main()
{
  cin >> n;
  for (int i = 1; i <= n; i ++)
  {
    int x;
    cin >> x;
    z[x].push_back(i << 1);
    z[x].push_back(i << 1 | 1);
    z[i << 1].push_back(x);
    z[i << 1 | 1].push_back(x);
  }
  dfs1(1);
  dfs2(1, 1);
  for (int i = 1; i <= 9; i ++)
    cerr << dep[i] << ' ';
  cerr << '\n';
  for (int i = 1; i <= (n << 1 | 1); i ++)
    cout << qdis(1, i) << '\n';
  return 0;
}

posted @ 2022-10-23 14:46  yhbqwq  阅读(51)  评论(0编辑  收藏  举报