제출 #1279313

#제출 시각아이디문제언어결과실행 시간메모리
1279313uranium235조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2)C++17
0 / 100
1 ms332 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; struct state { set<int> members; map<int, int> inEdges; // ll within = 0, inSum = 0; void merge(state &x) { assert(members.size() >= x.members.size()); // cout << "premerge " << within << endl; for (int i : x.members) { map<int, int>::iterator it = inEdges.find(i); if (it != inEdges.end()) { // within += it->second; // inSum -= it->second; inEdges.erase(it); } } for (map<int, int>::iterator it = x.inEdges.begin(); it != x.inEdges.end(); it++) { // edge from larger to smaller if (members.find(it->first) != members.end()) { // within += it->second; } else { inEdges[it->first] += it->second; // inSum += it->second; } } members.insert(x.members.begin(), x.members.end()); // cout << "postmerge " << endl; } ll ans() { ll sz = members.size(); return sz * (sz - 1) + inEdges.size() * sz; } }; int main() { ios::sync_with_stdio(false); cin.tie(0); int n, m; cin >> n >> m; vector<state> states(n); for (int i = 0; i < n; i++) states[i].members.insert(i); vector<int> parents(n); iota(parents.begin(), parents.end(), 0); auto par = [&](int v, auto &&self) -> int { return parents[v] == v ? v : (parents[v] = self(parents[v], self)); }; vector<set<int>> adj(n), radj(n); ll ans = 0; for (int i = 0; i < m; i++) { int a, b; cin >> a >> b; a--, b--; int ar = par(a, par), br = par(b, par); ans -= states[ar].ans(); ans -= states[br].ans(); if (ar == br) { // states[ar].within++; } else { states[br].inEdges[a]++; // states[br].inSum++; adj[br].insert(ar); radj[ar].insert(br); } ans += states[ar].ans(); ans += states[br].ans(); if (adj[ar].find(br) != adj[ar].end()) { if (states[ar].members.size() < states[br].members.size()) swap(ar, br); ans -= states[ar].ans(); ans -= states[br].ans(); parents[br] = ar; states[ar].merge(states[br]); ans += states[ar].ans(); for (int j : radj[br]) { set<int>::iterator it = adj[j].find(br); assert(it != adj[j].end()); adj[j].insert(ar); adj[j].erase(it); } adj[ar].insert(adj[br].begin(), adj[br].end()); } // cout << "i " << i << " " << ans << endl; cout << ans << '\n'; } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...