Submission #1028073

#TimeUsernameProblemLanguageResultExecution timeMemory
1028073BelphegorSplit the Attractions (IOI19_split)C++14
0 / 100
53 ms26964 KiB
#include "split.h"
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pi;
const int sz = 500000;
vector<int>tree[sz+5];
int sub[sz+5],visited[sz+5],idx,cnt;
int DFS(int cur){
	sub[cur] = 1;
	for(int nxt : tree[cur]){
		if(!sub[nxt]) sub[cur]+=DFS(nxt);
	}
	return sub[cur];
}
void dfs(int cur,vector<int>&v){
	if(!cnt) return;
	visited[cur] = 1; v[cur] = idx; cnt--;
	for(int nxt : tree[cur]){
		if(!visited[nxt]) dfs(nxt,v);
	}
}
struct UF{
	vector<int>p;
	UF(int n){
		p = vector<int>(n+3,-1);
	}
	void init(){
		for(int i=0; i<p.size(); i++) p[i] = -1;
	}
	int f(int a){
		if(p[a] < 0) return a;
		return p[a] = f(p[a]);
	}
	void merge(int a,int b){
		a = f(a); b = f(b);
		if(a!=b){
			p[a]+=p[b];
			p[b] = a;
		}
	}
	int get_size(int x){
		x = f(x);
		return -p[x];
	}
};
vector<int> find_split(int n, int A, int B, int C, vector<int> p, vector<int> q) {
	if(A > C) swap(A,C);
	if(B > C) swap(B,C);
	if(A > B) swap(A,B);
	assert(A <= B && B <= C);
	vector<pi>edge;
	UF uf(n);
	for(int i=0; i<p.size(); i++){
		int a = p[i],b = q[i];
		if(uf.f(a) == uf.f(b)){
			edge.emplace_back(pi(a,b));
			continue;
		}
		uf.merge(a,b);
		tree[a].emplace_back(b);
		tree[b].emplace_back(a);
	}
	DFS(0);
	int cen = 0;
	while(1){
		int mx = 0,child = -1;
		for(int nxt : tree[cen]){
			if(sub[nxt] > sub[cen]) continue;
			if(sub[nxt] > mx){
				mx = sub[nxt];
				child = nxt;
			}
		}
		if(mx > n/2) cen = child;
		else break;
	}
	//c is centroid
	uf.init();
	for(int i=0; i<n; i++){
		for(int nxt : tree[i]){
			if(i == cen || nxt == cen) continue;
			uf.merge(i,nxt);
		}
	}
	int s = -1;
	for(int i=0; i<n; i++){
		if(i == cen) continue;
		if(uf.get_size(i) >= A) s = i;
	}
	if(s<0){
		for(pi px : edge){
			int a = px.first,b = px.second;
			if(a == cen || b == cen) continue;
			tree[a].emplace_back(b);
			tree[b].emplace_back(a);
			uf.merge(a,b);
			if(uf.get_size(a) >= A) s = a;
			if(uf.get_size(b) >= A) s = b;
			if(s >= 0) break;
		}
	}
	if(s<0){return vector<int>(n,0);}
	
	vector<int>v = vector<int>(n,3);
	visited[cen] = 1;
	idx = 1; cnt = A; dfs(s,v); assert(cnt == 0);
	visited[cen] = 0;
	idx = 2; cnt = B; dfs(cen,v); assert(cnt == 0);
	return v;
}

Compilation message (stderr)

split.cpp: In member function 'void UF::init()':
split.cpp:28:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   28 |   for(int i=0; i<p.size(); i++) p[i] = -1;
      |                ~^~~~~~~~~
split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:53:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   53 |  for(int i=0; i<p.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...
#Verdict Execution timeMemoryGrader output
Fetching results...