Submission #67427

#TimeUsernameProblemLanguageResultExecution timeMemory
67427aomeCollapse (JOI18_collapse)C++17
100 / 100
5469 ms79620 KiB
#include "collapse.h"

#include <bits/stdc++.h>

using namespace std;

const int N = 100005;

struct Event {
	int T, type, x, y;

	bool operator < (const Event& rhs) const {
		return (T == rhs.T) ? type < rhs.type : T < rhs.T;
	}
};

struct Edge {
	int id, u, v;

	bool operator < (const Edge& rhs) const {
		return u < rhs.u;
	}
};

int n;
int par[N];
int res[N];
int f[2][N];
int pos[N];
bool state[N];
bool iedge[N];
bool inode[N];
vector<Event> vec, buf;
vector< pair<int, int> > dsu[2][500];
map< pair<int, int>, int > label;
vector<Edge> E1, E2;

int find(int u) { return u == par[u] ? u : par[u] = find(par[u]); }

bool join(int u, int v) {
	u = find(u), v = find(v);
	if (inode[u]) swap(u, v); // root prefer important node
	par[u] = v; return u != v; 
}

void solve() {
	vector<int> vnode;
	vector<Edge> vedge;

	int cnt = 0;
	for (auto i : buf) {
		if (i.type < 0) {
			int id = label[{i.x, i.y}];
			if (!iedge[id]) {
				iedge[id] = 1;
				vedge.push_back({id, i.x, i.y});
			}
			if (!inode[i.x]) {
				inode[i.x] = 1, vnode.push_back(i.x);
			}
			if (!inode[i.y]) {
				inode[i.y] = 1, vnode.push_back(i.y);
			}
		}
		else pos[i.type] = cnt++;
	}

	{	
		vector< pair<int, int> > vec1;
		for (auto i : buf) {
			if (i.type >= 0) vec1.push_back({i.x, i.type});
		}
		sort(vec1.begin(), vec1.end());
		for (int i = 0; i < n; ++i) par[i] = i;
		int ptr = 0, cur = 0, cnt = 0;
		for (auto i : vec1) {
			while (cur < i.first) ++cur, ++cnt;
			while (ptr < E1.size() && E1[ptr].u <= i.first) {
				if (!iedge[E1[ptr].id] && state[E1[ptr].id]) {
					cnt -= join(E1[ptr].u, E1[ptr].v);
				}
				++ptr;
			}
			f[0][i.second] = cnt;
			for (auto j : vnode) {
				dsu[0][pos[i.second]].push_back({j, find(j)});
			}
		}
	}

	{	
		vector< pair<int, int> > vec2;
		for (auto i : buf) {
			if (i.type >= 0) vec2.push_back({i.x + 1, i.type});
		}
		sort(vec2.begin(), vec2.end());
		reverse(vec2.begin(), vec2.end());
		for (int i = 0; i < n; ++i) par[i] = i;
		int ptr = 0, cur = 0, cnt = 0;
		for (auto i : vec2) {
			while (cur < n - i.first + 1) ++cur, ++cnt;
			while (ptr < E2.size() && E2[ptr].u >= i.first) {
				if (!iedge[E2[ptr].id] && state[E2[ptr].id]) {
					cnt -= join(E2[ptr].u, E2[ptr].v);
				}
				++ptr;
			}
			f[1][i.second] = cnt;
			for (auto j : vnode) {
				dsu[1][pos[i.second]].push_back({j, find(j)});
			}
		}
	}

	for (auto i : buf) {
		if (i.type < 0) {
			int id = label[{i.x, i.y}];
			state[id] ^= 1; continue;
		}
		int id = i.type;
		for (int j = 0; j < 2; ++j) {
			for (auto k : dsu[j][pos[id]]) par[k.first] = k.second;
			for (auto k : vnode) {
				if (j == 0 && k > i.x || j == 1 && k <= i.x) continue; 
				f[j][id] -= par[k] == k;
			}
			for (auto k : vedge) {
				// k.u < k.v
				if (state[k.id] && (k.v <= i.x || k.u > i.x)) join(k.u, k.v);
			}
			for (auto k : vnode) {
				if (j == 0 && k > i.x || j == 1 && k <= i.x) continue;
				f[j][id] += par[k] == k;
			}
		}
		res[id] = f[0][id] + f[1][id];
	}

	for (int i = 0; i < cnt; ++i) dsu[0][i].clear(), dsu[1][i].clear();
	for (auto i : buf) {
		if (i.type < 0) {
			iedge[label[{i.x, i.y}]] = inode[i.x] = inode[i.y] = 0;
		}
	}
	buf.clear();
}

vector<int> simulateCollapse(
	int _n,
	vector<int> T,
	vector<int> X,
	vector<int> Y,
	vector<int> W,
	vector<int> P
) {
	n = _n;
	int c = T.size();
	int q = W.size();

	for (int i = 0; i < c; ++i) {
		if (X[i] > Y[i]) swap(X[i], Y[i]);
		vec.push_back({i, -(T[i] + 1), X[i], Y[i]});
	}
	for (int i = 0; i < q; ++i) {
		vec.push_back({W[i], i, P[i], 0});
	}
	sort(vec.begin(), vec.end());

	int cnt = 0;
	for (int i = 0; i < c; ++i) {
		if (label[{X[i], Y[i]}]) continue;
		label[{X[i], Y[i]}] = ++cnt; 
		E1.push_back({cnt, Y[i], X[i]});
		E2.push_back({cnt, X[i], Y[i]});
	}

	sort(E1.begin(), E1.end());
	sort(E2.begin(), E2.end());
	reverse(E2.begin(), E2.end());

	for (int i = 0; i < vec.size(); ++i) {
		buf.push_back(vec[i]);
		if (buf.size() == 365) solve();
	}
	if (buf.size()) solve();

	vector<int> vres;
	for (int i = 0; i < q; ++i) vres.push_back(res[i]);
	return vres;
}

Compilation message (stderr)

collapse.cpp: In function 'void solve()':
collapse.cpp:78:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    while (ptr < E1.size() && E1[ptr].u <= i.first) {
           ~~~~^~~~~~~~~~~
collapse.cpp:102:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    while (ptr < E2.size() && E2[ptr].u >= i.first) {
           ~~~~^~~~~~~~~~~
collapse.cpp:124:16: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
     if (j == 0 && k > i.x || j == 1 && k <= i.x) continue; 
         ~~~~~~~^~~~~~~~~~
collapse.cpp:132:16: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
     if (j == 0 && k > i.x || j == 1 && k <= i.x) continue;
         ~~~~~~~^~~~~~~~~~
collapse.cpp: In function 'std::vector<int> simulateCollapse(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
collapse.cpp:181:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < vec.size(); ++i) {
                  ~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...