QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#555805#2214. Link Cut DigraphetohariWA 395ms72084kbC++203.3kb2024-09-10 10:09:302024-09-10 10:09:30

Judging History

你现在查看的是最新测评结果

  • [2024-09-10 10:09:30]
  • 评测
  • 测评结果:WA
  • 用时:395ms
  • 内存:72084kb
  • [2024-09-10 10:09:30]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

namespace std {
#ifndef LOCAL
#define cerr \
  if (0) cerr
#endif
}  // namespace std

struct DSU {
  vector<int> par;
  int64_t cur_ans;

  DSU(int n = 0) {
    par.assign(n + 5, -1);
    cur_ans = 0;
  }

  int root(int u) {
    if (par[u] < 0)
      return u;
    return par[u] = root(par[u]);
  }

  int size(int u) {
    return -par[root(u)];
  }

  bool join(int u, int v) {
    u = root(u);
    v = root(v);
    if (u == v)
      return false;
    cur_ans += 1ll * -par[u] * -par[v];
    if (par[u] > par[v])
      swap(u, v);
    par[u] += par[v];
    par[v] = u;
    return true;
  }
};

const int N = 2.5e5 + 5;

int n, m;
pair<int, int> ed[N];

DSU dsu(N);
int64_t ans[N];
vector<int> nodes;
vector<int> g[N];
int low[N], num[N], time_dfs, del[N];
int id_scc[N];
vector<int> stk;
vector<vector<int>> scc;
vector<int> T[N];

void dfs(int u) {
  low[u] = num[u] = ++time_dfs;
  stk.push_back(u);
  for (int v : g[u]) {
    if (del[v]) {
      continue;
    }
    if (!num[v]) {
      dfs(v);
      low[u] = min(low[u], low[v]);
    } else {
      low[u] = min(low[u], num[v]);
    }
  }
  if (low[u] == num[u]) {
    scc.push_back({});
    int v;
    do {
      v = stk.back();
      scc.back().push_back(v);
      id_scc[v] = scc.size();
      del[v] = 1;
      stk.pop_back();
    } while (v != u);
  }
}

void add_edge(int u, int v) {
  nodes.push_back(u);
  nodes.push_back(v);
  g[u].push_back(v);
}

void reset() {
  for (int u : nodes) {
    low[u] = num[u] = del[u] = 0;
    id_scc[u] = 0;
    g[u].clear();
  }
  nodes.clear();
  stk.clear();
  scc.clear();
  time_dfs = 0;
}

void solve(int l, int r, vector<int> edges) {
  if (l > r) {
    return;
  }
  int mid = (l + r) >> 1;
  reset();
  for (int i : edges) {
    if (i <= mid) {
      auto [x, y] = ed[i];
      x = dsu.root(x);
      y = dsu.root(y);
      add_edge(x, y);
    }
  }
  for (int u : nodes) {
    if (!num[u]) {
      dfs(u);
    }
  }
  vector<vector<int>> cur_scc = scc;
  vector<int> g1, g2;
  for (int i : edges) {
    if (i <= mid) {
      auto [u, v] = ed[i];
      u = dsu.root(u), v = dsu.root(v);
      if (id_scc[u] == id_scc[v]) {
        T[mid].push_back(i);
        g1.push_back(i);
      } else {
        g2.push_back(i);
      }
    } else {
      g2.push_back(i);
    }
  }
  solve(l, mid - 1, g1);
  solve(mid + 1, r, g2);
  for (int i : g1) {
    dsu.join(ed[i].first, ed[i].second);
  }
  // for (auto v : cur_scc) {
  //   for (auto i : v) {
  //     dsu.join(i, v.front());
  //   }
  // }
  edges.clear();
  g1.clear();
  g2.clear();
}

int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
#ifdef LOCAL
#define task "a"
#else
#define task ""
#endif
  if (fopen(task ".inp", "r")) {
    freopen(task ".inp", "r", stdin);
    freopen(task ".out", "w", stdout);
  }
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    auto& [u, v] = ed[i];
    cin >> u >> v;
  }
  vector<int> id(m);
  iota(id.begin(), id.end(), 1);
  solve(1, m, id);
  dsu = DSU(n);
  for (int i = 1; i <= m; i++) {
    for (auto id : T[i]) {
      dsu.join(ed[id].first, ed[id].second);
    }
    cout << dsu.cur_ans << "\n";
  }
  return 0;
}

Details

Test #1:

score: 0
Wrong Answer
time: 395ms
memory: 72084kb