QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#76565#2214. Link Cut DigraphSanguineChameleonAC ✓790ms385240kbC++204.0kb2023-02-10 20:13:032023-02-10 20:13:06

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-02-10 20:13:06]
  • 评测
  • 测评结果:AC
  • 用时:790ms
  • 内存:385240kb
  • [2023-02-10 20:13:03]
  • 提交

answer

// BEGIN BOILERPLATE CODE

#include <bits/stdc++.h>
using namespace std;

#ifdef KAMIRULEZ
	const bool kami_loc = true;
	const long long kami_seed = 69420;
#else
	const bool kami_loc = false;
	const long long kami_seed = chrono::steady_clock::now().time_since_epoch().count();
#endif

const string kami_fi = "kamirulez.inp";
const string kami_fo = "kamirulez.out";
mt19937_64 kami_gen(kami_seed);

long long rand_range(long long rmin, long long rmax) {
	uniform_int_distribution<long long> rdist(rmin, rmax);
	return rdist(kami_gen);
}

long double rand_real(long double rmin, long double rmax) {
	uniform_real_distribution<long double> rdist(rmin, rmax);
	return rdist(kami_gen);
}

void file_io(string fi, string fo) {
	if (fi != "" && (!kami_loc || fi == kami_fi)) {
		freopen(fi.c_str(), "r", stdin);
	}
	if (fo != "" && (!kami_loc || fo == kami_fo)) {
		freopen(fo.c_str(), "w", stdout);
	}
}

void set_up() {
	if (kami_loc) {
		file_io(kami_fi, kami_fo);
	}
	ios_base::sync_with_stdio(0);
	cin.tie(0);
}

void just_do_it();

void just_exec_it() {
	if (kami_loc) {
		auto pstart = chrono::steady_clock::now();
		just_do_it();
		auto pend = chrono::steady_clock::now();
		long long ptime = chrono::duration_cast<chrono::milliseconds>(pend - pstart).count();
		string bar(50, '=');
		cout << '\n' << bar << '\n';
		cout << "Time: " << ptime << " ms" << '\n';
	}
	else {
		just_do_it();
	}
}

int main() {
	set_up();
	just_exec_it();
	return 0;
}

// END BOILERPLATE CODE

// BEGIN MAIN CODE

vector<long long> R;

struct node {
	int id = 0;
	int sz = 0;
	bool f = false;
	vector<node*> adj1, adj2;
	node *cmp = nullptr;

	node() {

	}

	node(int _id, int _sz) {
		id = _id;
		sz = _sz;
	}
};

struct edge {
	node *u = nullptr;
	node *v = nullptr;

	int t = 0;

	edge() {

	}

	edge(node *_u, node *_v, int _t) {
		u = _u;
		v = _v;
		t = _t;
	}
};

struct graph {
	int lt = 0;
	int rt = 0;
	vector<edge> E;
	node *cur = nullptr;
	long long res = 0;

	deque<node*> topo;

	void dfs1(node *u) {
		u->f = true;
		for (auto v: u->adj1) {
			if (!v->f) {
				dfs1(v);
			}
		}
		topo.push_front(u);
	}

	void dfs2(node *u) {
		res -= 1LL * u->sz * (u->sz - 1) / 2;
		cur->sz += u->sz;
		u->cmp = cur;
		for (auto v: u->adj2) {
			if (!v->cmp) {
				dfs2(v);
			}
		}
	}

	void solve() {
		long long tmp = res;
		int mt = (lt + rt) / 2;
		for (auto e: E) {
			if (e.t <= mt) {
				e.u->adj1.push_back(e.v);
				e.v->adj2.push_back(e.u);
			}
		}
		for (auto e: E) {
			if (e.t <= mt) {
				if (!e.u->f) {
					dfs1(e.u);
				}
				if (!e.v->f) {
					dfs1(e.v);
				}
			}
		}
		for (auto u: topo) {
			if (!u->cmp) {
				cur = new node(u->id, 0);
				dfs2(u);
				res += 1LL * cur->sz * (cur->sz - 1) / 2;
			}
		}
		if (lt == rt) {
			R[lt] = res;
			return;
		}
		graph Gl, Gr;
		Gl.lt = lt;
		Gl.rt = mt;
		Gl.res = tmp;
		Gr.lt = mt + 1;
		Gr.rt = rt;
		Gr.res = res;
		vector<edge> L;
		for (auto e: E) {
			if (!e.u->cmp) {
				e.u->cmp = new node(e.u->id, e.u->sz);
			}
			if (!e.v->cmp) {
				e.v->cmp = new node(e.v->id, e.v->sz);
			}
			if (e.t <= mt && e.u->cmp == e.v->cmp) {
				L.push_back(e);
			}
			else {
				Gr.E.emplace_back(e.u->cmp, e.v->cmp, max(e.t, mt + 1));
			}
		}
		for (auto e: E) {
			e.u->cmp = nullptr;
			e.v->cmp = nullptr;
		}
		for (auto e: L) {
			if (!e.u->cmp) {
				e.u->cmp = new node(e.u->id, e.u->sz);
			}
			if (!e.v->cmp) {
				e.v->cmp = new node(e.v->id, e.v->sz);
			}
			Gl.E.emplace_back(e.u->cmp, e.v->cmp, e.t);
		}
		Gl.solve();
		Gr.solve();
	}
} G;

void just_do_it() {
	int n, m;
	cin >> n >> m;
	G.lt = 1;
	G.rt = m;
	vector<node*> a(n + 1);
	for (int i = 1; i <= n; i++) {
		a[i] = new node();
		a[i]->id = i;
		a[i]->sz = 1;
	}
	R.resize(m + 1);
	for (int i = 1; i <= m; i++) {
		int u, v;
		cin >> u >> v;
		G.E.emplace_back(a[u], a[v], i);
	}
	G.solve();
	for (int i = 1; i <= m; i++) {
		cout << R[i] << '\n';
	}
}

// END MAIN CODE

詳細信息

Test #1:

score: 100
Accepted
time: 784ms
memory: 372216kb

Test #2:

score: 0
Accepted
time: 790ms
memory: 372540kb

Test #3:

score: 0
Accepted
time: 754ms
memory: 372604kb

Test #4:

score: 0
Accepted
time: 753ms
memory: 385240kb

Test #5:

score: 0
Accepted
time: 742ms
memory: 373684kb

Test #6:

score: 0
Accepted
time: 735ms
memory: 372992kb

Test #7:

score: 0
Accepted
time: 779ms
memory: 373448kb

Test #8:

score: 0
Accepted
time: 753ms
memory: 373692kb

Test #9:

score: 0
Accepted
time: 767ms
memory: 378012kb

Test #10:

score: 0
Accepted
time: 754ms
memory: 374128kb

Test #11:

score: 0
Accepted
time: 695ms
memory: 373048kb

Test #12:

score: 0
Accepted
time: 755ms
memory: 373296kb

Test #13:

score: 0
Accepted
time: 790ms
memory: 375560kb

Test #14:

score: 0
Accepted
time: 701ms
memory: 374048kb

Test #15:

score: 0
Accepted
time: 420ms
memory: 220824kb

Test #16:

score: 0
Accepted
time: 641ms
memory: 331068kb

Test #17:

score: 0
Accepted
time: 642ms
memory: 329356kb

Test #18:

score: 0
Accepted
time: 781ms
memory: 330204kb

Test #19:

score: 0
Accepted
time: 750ms
memory: 373624kb

Test #20:

score: 0
Accepted
time: 734ms
memory: 371168kb

Test #21:

score: 0
Accepted
time: 728ms
memory: 374296kb

Test #22:

score: 0
Accepted
time: 761ms
memory: 377592kb

Test #23:

score: 0
Accepted
time: 751ms
memory: 371532kb

Test #24:

score: 0
Accepted
time: 690ms
memory: 375928kb

Test #25:

score: 0
Accepted
time: 710ms
memory: 372588kb

Test #26:

score: 0
Accepted
time: 706ms
memory: 368764kb

Test #27:

score: 0
Accepted
time: 706ms
memory: 365680kb