求助关于点分治写法复杂度
  • 板块学术版
  • 楼主YBaggio
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/2/27 15:34
  • 上次更新2024/2/27 18:52:03
查看原帖
求助关于点分治写法复杂度
507534
YBaggio楼主2024/2/27 15:34

原题:CF1923D 我的代码:

#include <iostream>
#include <vector>
#pragma GCC optimize ("Ofast")
#pragma GCC optimize (3)
#define inf 1000000000
using namespace std;
typedef long long ll;
const int maxn = 200010;
int T;
int n, a[maxn], cnt, h[maxn];
int s[maxn], ms[maxn];
int sum, rt;
bool vis[maxn];
int b[maxn], c[maxn];
ll ans;
vector <int> t, _t;
struct E {
  int to, ne;
} e[maxn << 1];
void add (int u, int v) {
  e[++cnt].to = v; e[cnt].ne = h[u]; h[u] = cnt;
}
void find (int x, int fa) {
  ms[x] = 0;
  s[x] = 1;
  for (int i = h[x]; i; i = e[i].ne) {
    int y = e[i].to;
    if (!vis[y] && y != fa) {
      find (y, x);
      s[x] += s[y];
      ms[x] = max (ms[x], y);
    }
  }
  ms[x] = max (ms[x], sum - s[x]);
  if (ms[x] < ms[rt]) rt = x;
}
void getinfo (int x, int fa) {
  if (!b[a[x]]) t.push_back (a[x]);
  b[a[x]]++;
  for (int i = h[x]; i; i = e[i].ne) {
    int y = e[i].to;
    if (!vis[y] && y != fa) {
      getinfo (y, x);
    }
  }
  b[a[x]]--;
}
void dfs (int x, int fa) {
  vis[x] = true;
  for (int i = h[x]; i; i = e[i].ne) {
    int y = e[i].to;
    if (y != fa && !vis[y]) {
      getinfo (y, x);
      for (int d : t) {
        if (d == a[x]) ans++;
        else ans += c[d];
      } 
      for (int d : t) {
        if (c[d]++ == 0) _t.push_back (d);
      }
    }
    t.clear ();
  }
  for (int x : _t) c[x] = 0;
  _t.clear ();
  for (int i = h[x]; i; i = e[i].ne) {
    int y = e[i].to;
    if (y != fa && !vis[y]) {
      sum = s[y];
      ms[rt = 0] = inf;
      find (y, x);
      find (rt, 0);
      dfs (rt, x);
    }    
  }
}
int main () {
  ios::sync_with_stdio (false);
  cin.tie (0);
  cin >> T;
  while (T--) {
    cin >> n;
    fill (vis + 1, vis + n + 1, false);
    fill (h + 1, h + n + 1, 0);
    fill (c + 1, c + n + 1, 0);
    ans = cnt = 0;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i < n; i++) {
      int u, v; cin >> u >> v;
      add (u, v); add (v, u);
    }
    ms[rt = 0] = inf;
    sum = n;
    find (1, 0);
    find (rt, 0);
    dfs (rt, 0);
    cout << ans << '\n';
  }
  return 0;
}

请问我的写法复杂度是否正确?或者有什么对于此题来说很慢的地方呢?

2024/2/27 15:34
加载中...