Submission #1047523

#TimeUsernameProblemLanguageResultExecution timeMemory
1047523vjudge1Split the Attractions (IOI19_split)C++17
40 / 100
46 ms34908 KiB
#include "split.h"
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define pb push_back
#define ff first
#define all(x) x.begin(), x.end()
#define ss second
const int N = 5e5;

int n;
vector<int> g[N];
vector<int> res;
vector<bool> vis;
vector<vector<bool>> edge;
int par[N];

void fill(int v, int par, int col, int &colnum){
	queue<int> q;
	q.push(v);
	vis[v] = 1;
	vis[par] = 1;
	res[v] = col;
	--colnum;
	while(!q.empty()){
		int v = q.front();
		q.pop();
		// cout << v << ' ' << a << ' ' << b << ' ' << c << '\n';
		
		for(int u: g[v]){
			if(!vis[u]){
				if(colnum > 0 && (n >= 3000 || edge[u][v])){
					res[u] = col;
					--colnum;
					// cout << v << ' ' << 2 << '\n';
				}else break;
				vis[u] = 1;
				q.push(u);
			}
		}
		if(colnum == 0) break;
	}
	vis[par] = 0;
}


vector<bool> viss;
int sz[N], tin[N], tout[N], timer = 0;
void dfs(int v, int p){
	sz[v] = 1;
	par[v] = p;
	tin[v] = timer++;
	viss[v] = 1;
	for(int u: g[v]){
		if(u != p && !viss[u]){
			if(n < 3000){
				edge[u][v] = edge[v][u] = 1;
			}
			dfs(u, v);
			sz[v] += sz[u];
		}
	}
	tout[v] = timer++;
}
bool is_ancestor(int u, int v){
	return tin[u] <= tin[v] && tout[v] <= tout[u];
}
vector<int> find_split(int nn, int a, int b, int c, vector<int> Y, vector<int> X) {
	n = nn;

	vector<pair<int, int>> arr;
	arr.pb({a, 1});
	arr.pb({b, 2});
	arr.pb({c, 3});
	sort(all(arr));

	for(int i = 1; i < Y.size(); ++i){
		int r = rand() % i;
		swap(Y[i], Y[r]);
		swap(X[i], X[r]);
	}
	for(int i = 0; i < Y.size(); ++i){
		g[Y[i]].pb(X[i]);
		g[X[i]].pb(Y[i]);
	}

	if(n < 3000){
		int root = 0;
		edge.resize(n, vector<bool>(n));
		res.clear();
		res.resize(n+1);
		vis.clear();
		vis.resize(n+1);
		viss.clear();
		viss.resize(n+1);
		dfs(root, n);

		bool ok = 0;
		int A = 0;
		for(int i = 0; i < n; ++i){
			if(i == root) continue;
			if(sz[i] >= arr[0].ff && sz[root] - sz[i] >= arr[1].ff){
				fill(i, par[i], arr[0].ss, arr[0].ff);
				fill(root, par[root], arr[1].ss, arr[1].ff);
				ok = 1;
				break;
			}else if(sz[i] >= arr[1].ff && sz[root] - sz[i] >= arr[0].ff){
				fill(i, par[i], arr[1].ss, arr[1].ff);
				fill(root, par[root], arr[0].ss, arr[0].ff);
				ok = 1;
				break;
			}
			if(sz[i] >= arr[0].ff) A = 1;
		}
		if(!ok && A == 0){
			res.pop_back();
			return res;
		}
		if(ok){
			res.pop_back();
			for(int &cc: res) if(cc == 0) cc = arr[2].ss;
			return res;
		}

		for(int v = 1; v < n; ++v){
			if(sz[v] >= arr[0].ff){ // v kotu node
				vector<pair<int, int>> good;
				int tot = 0;
				for(int u = 1; u < n; ++u){
					if(is_ancestor(v, u) && u != v && sz[u] < arr[0].ff && sz[par[u]] >= arr[0].ff){ // kendi iyi, parenti kotu
						bool k = 0;
						for(int j: g[u]){
							if(is_ancestor(v, j) == 0) k = 1;
						}
						if(k){
							good.pb({sz[u], u});
							tot += sz[u];
						}
					}
				}
				if(sz[root] - (sz[v] - tot) >= arr[0].ff){
					sort(all(good));
					vector<int> U;
					for(auto p: good){
						if(sz[root] - sz[v] < arr[0].ff){
							sz[v] -= p.ff;
							U.pb(p.ss);
						}else break;
					}
					if(sz[root] - sz[v] >= arr[0].ff && sz[v] >= arr[1].ff){
						for(int u: U){
							fill(u, par[u], arr[0].ss, arr[0].ff);
						}
						fill(v, par[v], arr[1].ss, arr[1].ff);
						fill(root, par[root], arr[0].ss, arr[0].ff);
					}else{
						for(int u: U){
							fill(u, par[u], arr[1].ss, arr[1].ff);
						}
						fill(v, par[v], arr[0].ss, arr[0].ff);
						fill(root, par[root], arr[1].ss, arr[1].ff);
					}
					
					ok = 1;
					break;
				}
			}
		}
		if(!ok){
			res.pop_back();
			return res;
		}

		res.pop_back();
		for(int &cc: res) if(cc == 0) cc = arr[2].ss;
		return res;
	}	
	

	
	


	for(int root = 0; root < n; ++root){
		res.clear();
		res.resize(n+1);
		vis.clear();
		vis.resize(n+1);
		viss.clear();
		viss.resize(n+1);
		dfs(root, n);

	

		bool ok = 0;
		for(int i = 0; i < n; ++i){
			if(i == root) continue;
			if(sz[i] >= arr[0].ff && sz[root] - sz[i] >= arr[1].ff){
				fill(i, par[i], arr[0].ss, arr[0].ff);
				fill(root, par[root], arr[1].ss, arr[1].ff);
				ok = 1;
				break;
			}else if(sz[i] >= arr[1].ff && sz[root] - sz[i] >= arr[0].ff){
				fill(i, par[i], arr[1].ss, arr[1].ff);
				fill(root, par[root], arr[0].ss, arr[0].ff);
				ok = 1;
				break;
			}
		}
		if(!ok){
			if(X.size() == nn-1) break;
			continue;
		}
		res.pop_back();
		for(int &cc: res) if(cc == 0) cc = arr[2].ss;
		return res;
	}
	res.pop_back();
	return res;
}

Compilation message (stderr)

split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:77:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   77 |  for(int i = 1; i < Y.size(); ++i){
      |                 ~~^~~~~~~~~~
split.cpp:82:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   82 |  for(int i = 0; i < Y.size(); ++i){
      |                 ~~^~~~~~~~~~
split.cpp:211:16: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  211 |    if(X.size() == nn-1) break;
      |       ~~~~~~~~~^~~~~~~
#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...