水题求卡常
  • 板块学术版
  • 楼主yhylivedream
  • 当前回复3
  • 已保存回复3
  • 发布时间2024/12/10 17:08
  • 上次更新2024/12/10 20:51:11
查看原帖
水题求卡常
778022
yhylivedream楼主2024/12/10 17:08

Vertex Pairs,尝试将倍增LCA替换成其他方式,但无果。

#include <bits/stdc++.h>

using namespace std;
using Pii = pair<int, int>;

const int kMaxN = 4e5 + 5, kL = 20;

int n, a[kMaxN], tag[kMaxN], vis[kMaxN], d[kMaxN], f[kMaxN][kL];
vector<int> e[kMaxN];
Pii p[kMaxN];

void Init(int x, int fa) {
  f[x][0] = fa, d[x] = d[fa] + 1;
  for (int i = 1; i < kL; i++) {
    f[x][i] = f[f[x][i - 1]][i - 1];
  }
  for (int nxt : e[x]) {
    nxt != fa && (Init(nxt, x), 0);
  }
}
void PushDown(int x, int fa) {
  for (int nxt : e[x]) {
    if (nxt != fa) {
      PushDown(nxt, x);
      tag[x] |= tag[nxt];
    }
  }
}
void Update(int x) {
  for (; !vis[x]; x = f[x][0]) {
    vis[x] = 1;
  }
}
void S(int x, int fa) {
  if (x == p[a[x]].first) {
    Update(p[a[x]].second);
  } else {
    Update(p[a[x]].first);
  }
  for (int nxt : e[x]) {
    nxt != fa && (S(nxt, x), 0);
  }
}
int Lca(int x, int y) {
  d[x] > d[y] && (swap(x, y), 0);
  for (int i = 0; i < kL; i++) {
    ((d[y] - d[x]) >> i & 1) && (y = f[y][i]);
  }
  if (x == y) return x;
  for (int i = kL - 1; i >= 0; i--) {
    f[y][i] != f[x][i] && (x = f[x][i], y = f[y][i]);
  }
  return f[x][0];
}

vector<int> Calc(int rt) {
  fill(tag + 1, tag + 2 * n + 1, 0);
  fill(vis + 1, vis + 2 * n + 1, 0);
  vis[rt] = tag[rt] = 1;

  Init(rt, 0);
  for (int i = 1; i <= n; i++) {
    tag[Lca(p[i].first, p[i].second)] = 1;
  }
  PushDown(rt, 0);
  for (int i = 2 * n; i; i--) {
    if (!vis[i] && !tag[i]) {
      S(i, f[i][0]);
    }
  }
  vector<int> v;
  for (int i = 2 * n; i; i--) {
    v.push_back(vis[i]);
  }
  return v;
}

int main() {
  cin >> n;
  for (int i = 1; i <= 2 * n; i++) {
    cin >> a[i];
    !p[a[i]].first ? (p[a[i]].first = i) : (p[a[i]].second = i);
  }
  for (int i = 1, x, y; i < 2 * n; i++) {
    cin >> x >> y;
    e[x].push_back(y), e[y].push_back(x);
  }
  vector<int> v1 = Calc(p[1].first);
  vector<int> v2 = Calc(p[1].second);
  if (v1 < v2) {
    int cnt = 0;
    for (int x : v1) {
      cnt += x;
    }
    cout << cnt << '\n';
    for (int i = 0; i < v1.size(); i++) {
      if (v1[i]) {
        cout << 2 * n - i << ' ';
      }
    }
  } else {
    int cnt = 0;
    for (int x : v2) {
      cnt += x;
    }
    cout << cnt << '\n';
    for (int i = 0; i < v2.size(); i++) {
      if (v2[i]) {
        cout << 2 * n - i << ' ';
      }
    }
  }
}
2024/12/10 17:08
加载中...