답안 #1026581

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1026581 2024-07-18T08:13:39 Z Gray 조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2) C++17
0 / 100
1 ms 348 KB
// #pragma GCC optimize("O3")
// #pragma GCC target("avx2")
#include <algorithm>
#include <climits>
#include <ios>
#include<iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

#define ll long long
#define ff first
#define ss second
#define ull unsigned ll
#define ln "\n"
#define pll pair<ll, ll>
#define INF 2e18
using namespace std;

struct DSU{
	vector<set<ll>> h_in, h_out, lead;
	vector<ll> par, sz;
	ll n, ecnt;
	DSU(ll N){
		n=N;
		ecnt=0;
		par.resize(n+1, -1);
		h_in=h_out=lead = vector<set<ll>>(n+1);
		for (ll i=1; i<=n; i++) lead[i].insert(i);
		sz.resize(n+1, 1);
	}
	void debug(){
		return;
		for (ll i=1; i<=n; i++){
			cout << i << "::\n";
			cout << "lead: ";
			for (auto ch:lead[i]) cout << ch << ' ';
			cout << "\nin: ";
			for (auto ch:h_in[i]) cout << ch << ' ';
			cout << "\nout: ";
			for (auto ch:h_out[i]) cout << ch << ' ';
			cout << ln << ln;
		}
	}
	queue<pair<ll, ll>> unity;
	ll get(ll u){
		return par[u]==-1?u:par[u]=get(par[u]);
	}

	void elink(ll u, ll v, int add=1){
		ll pu = get(u), pv=get(v);
		// cout << "Request: " << u << "->" << v << " - " << pu << " -> " << pv << ln;
		if (pu==pv or h_in[pv].count(pu)){
			// if (add==0) cout << "Spec: " << u << " " << v << ln;
			return;
		}else if (h_out[pv].count(pu)){
			h_in[pv].insert(pu);
			h_out[pu].insert(pv);
			unity.push({pu, pv});
		}else{
			ecnt+=sz[v]*add;
			h_in[pv].insert(pu);
			h_out[pu].insert(pv);
			lead[pv].insert(u);
		}
	}
	void link(ll u, ll v){
		elink(u, v);
		proc_unities();
		debug();
	}
	void unite(ll u, ll v){
		u=get(u); v=get(v);
		if (u==v) return;
		if (h_in[u].size()+h_out[u].size()+lead[u].size()<h_in[v].size()+h_out[v].size()+lead[v].size()) swap(u, v);
		par[v]=u;
		// cout << "PDEB: " << ecnt << ":" << sz[u] << ' ' << sz[v] << ln;
		ecnt+=sz[u]*lead[v].size()+sz[v]*lead[u].size();
		sz[u]+=sz[v];
		// cout << "Unite: " << v << "->" << u << ln;
		// cout << "PDEB: " << ecnt << ln;
		for (auto mem:lead[v]){
			ecnt-=sz[u]*lead[u].count(mem);
			lead[u].insert(mem);
		}
		lead[v].clear();
		h_in[v].erase(u); h_out[u].erase(v);
		h_in[u].erase(v); h_out[v].erase(u);
		for (auto mem:h_in[v]){
			h_out[mem].erase(v);
			elink(mem, u, 0);
		}
		h_in[v].clear();
		for (auto mem:h_out[v]){
			h_in[mem].erase(v);
			elink(u, mem, 0);
		}
		h_out[v].clear();
	}
	void proc_unities(){
		while (!unity.empty()){
			auto cur = unity.front();
			unity.pop();
			unite(cur.ff, cur.ss);
		}
	}
};

void solve(){
	ll n, m; 
	cin >> n >> m;
	DSU tr(n);
	for (ll i=0; i<m; i++){
		ll u, v; cin >> u >> v;
		tr.link(u, v);
		cout << tr.ecnt << ln;
	}
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(nullptr);
	ll t=1;
	// cin >> t;
	while (t--) {
		solve();
	}
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 1 ms 348 KB Output is correct
3 Incorrect 1 ms 348 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 1 ms 348 KB Output is correct
3 Incorrect 1 ms 348 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 1 ms 348 KB Output is correct
3 Incorrect 1 ms 348 KB Output isn't correct
4 Halted 0 ms 0 KB -