제출 #1068203

#제출 시각아이디문제언어결과실행 시간메모리
1068203LittleOrangeSplit the Attractions (IOI19_split)C++17
40 / 100
686 ms1048576 KiB
#include "split.h"

#include<bits/stdc++.h>
using namespace std;
using ll = int;
struct dsu{
	vector<ll> p;
	dsu(ll N):p(N,-1){}
	ll g(ll i){
		return p[i]<0?i:p[i] = g(p[i]);
	}
	bool m(ll a,ll b){
		a = g(a),b = g(b);
		if (a==b) return false;
		if (p[a]>p[b]) swap(a,b);
		p[a] += p[b];
		p[b] = a;
		return true;
	}
};

vector<int> find_split(int n, int a, int b, int c, vector<int> p, vector<int> q) {
	mt19937_64 mt(random_device{}());
	vector<vector<ll>> con(n);
	ll m = p.size();
	for(ll i = 0;i<m;i++){
		con[p[i]].push_back(q[i]);
		con[q[i]].push_back(p[i]);
	}
	ll mxd = 0;
	for(auto &o : con) mxd = max(mxd,(ll)o.size());
	if (mxd==2){
		ll st = 0;
		for(ll i = 0;i<n;i++) if(con[i].size()==1) st = i;
		vector<ll> v(1,st);
		vector<ll> u(n,0);
		u[st] = 1;
		while(v.size()<n){
			for(ll i : con[st]) if(!u[i]){
				u[i] = 1;
				v.push_back(i);
				st = i;
				break;
			}
		}
		vector<ll> ret(n,0);
		for(ll i = 0;i<a;i++) ret[v[i]] = 1;
		for(ll i = a;i<a+b;i++) ret[v[i]] = 2;
		for(ll i = a+b;i<a+b+c;i++) ret[v[i]] = 3;
		return ret;
	}
	if (a==1){
		vector<ll> r(n,0);
		function<void(ll)> dfs;
		dfs = [&](ll i){
			if (r[i]||b==0) return;
			r[i] = 2;
			b--;
			for(ll j : con[i]){
				dfs(j);
			}
		};
		dfs(0);
		for(ll i = 0;i<n;i++)if(!r[i]){
			if (a){
				a=0;
				r[i] = 1;
			}else r[i] = 3;
		}
		return r;
	}
	vector<array<ll,2>> abc = {{a,1},{b,2},{c,3}};
	sort(abc.begin(),abc.end());
	if(m==n-1){
		vector<ll> c1(n,-1),c2(n,-1),s(n,1),P(n,-1);
		function<void(ll,ll)> dfs;
		dfs = [&](ll i,ll p){
			P[i] = p;
			for(ll j : con[i])if(j!=p) {
				dfs(j,i);
				s[i]+=s[j];
			}
			if (s[i]>=abc[0][0]) c1[i] = 0;
			if (s[i]>=abc[1][0]) c2[i] = 0;
			for(ll j : con[i])if(j!=p) {
				if (c1[j]>=0) c1[i] = max(c1[i],c1[j]+s[i]-s[j]);
				if (c2[j]>=0) c2[i] = max(c2[i],c2[j]+s[i]-s[j]);
			}
		};
		dfs(0,-1);
		//for(ll i = 0;i<n;i++) cerr << c1[i] << " \n"[i+1==n];
		//for(ll i = 0;i<n;i++) cerr << c2[i] << " \n"[i+1==n];
		vector<ll> res(n,0);
		if (c1[0]<abc[1][0]&&c2[0]<abc[0][0]) return res;
		//cerr << "sus\n";
		function<void(ll,ll)> draw;
		draw = [&](ll i, ll t){
			if (abc[t][0]==0||res[i]) return;
			abc[t][0]--;
			res[i] = abc[t][1];
			for(ll j : con[i])if(j!=P[i]) draw(j,t);
		};
		if (c1[0]>=abc[1][0]){
			function<ll(ll)> fd;
			fd = [&](ll i){
				if (c1[i]==0) return i;
				for(ll j : con[i])if(j!=P[i]&&c1[j]+s[i]-s[j]==c1[i]) {
					return fd(j);
				}
			};
			ll x = fd(0);
			draw(x,0);
			draw(0,1);
		}else{
			function<ll(ll)> fd;
			fd = [&](ll i){
				if (c2[i]==0) return i;
				for(ll j : con[i])if(j!=P[i]&&c2[j]+s[i]-s[j]==c2[i]) {
					return fd(j);
				}
			};
			ll x = fd(0);
			draw(x,1);
			draw(0,0);
		}
		for(ll i = 0;i<n;i++) if(res[i]==0) res[i] = abc[2][1];
		return res;
	}
	vector<pair<ll,ll>> ls;
	for(ll i = 0;i<m;i++) ls.push_back({p[i],q[i]});
	ll t0 = time(0);
	ll trycnt = 1000;
	while(time(0)<t0+2){
		shuffle(ls.begin(),ls.end(),mt);
		vector<vector<ll>> con(n);
		dsu d(n);
		for(auto [u,v] : ls)if(d.m(u,v)){
			con[u].push_back(v);
			con[v].push_back(u);
		}
		{
			ll root = 0;
			vector<ll> c1(n,-1),c2(n,-1),s(n,1),P(n,-1);
			function<void(ll,ll)> dfs;
			dfs = [&](ll i,ll p){
				P[i] = p;
				for(ll j : con[i])if(j!=p) {
					dfs(j,i);
					s[i]+=s[j];
				}
				if (s[i]>=abc[0][0]) c1[i] = 0;
				if (s[i]>=abc[1][0]) c2[i] = 0;
				for(ll j : con[i])if(j!=p) {
					if (c1[j]>=0) c1[i] = max(c1[i],c1[j]+s[i]-s[j]);
					if (c2[j]>=0) c2[i] = max(c2[i],c2[j]+s[i]-s[j]);
				}
			};
			dfs(root,-1);
			//for(ll i = 0;i<n;i++) cerr << c1[i] << " \n"[i+1==n];
			//for(ll i = 0;i<n;i++) cerr << c2[i] << " \n"[i+1==n];
			vector<ll> res(n,0);
			if (c1[0]<abc[1][0]&&c2[0]<abc[0][0]) continue;
			//cerr << "sus\n";
			function<void(ll,ll)> draw;
			draw = [&](ll i, ll t){
				if (abc[t][0]==0||res[i]) return;
				abc[t][0]--;
				res[i] = abc[t][1];
				for(ll j : con[i])if(j!=P[i]) draw(j,t);
			};
			if (c1[0]>=abc[1][0]){
				function<ll(ll)> fd;
				fd = [&](ll i){
					if (c1[i]==0) return i;
					for(ll j : con[i])if(j!=P[i]&&c1[j]+s[i]-s[j]==c1[i]) {
						return fd(j);
					}
				};
				ll x = fd(root);
				draw(x,0);
				draw(root,1);
			}else{
				function<ll(ll)> fd;
				fd = [&](ll i){
					if (c2[i]==0) return i;
					for(ll j : con[i])if(j!=P[i]&&c2[j]+s[i]-s[j]==c2[i]) {
						return fd(j);
					}
				};
				ll x = fd(root);
				draw(x,1);
				draw(root,0);
			}
			for(ll i = 0;i<n;i++) if(res[i]==0) res[i] = abc[2][1];
			return res;
		}
	}
	vector<int> res(n,0);
	/*if (n == 9) {
		res = {1, 1, 3, 1, 2, 2, 3, 1, 3};
	} else {
		res = {0, 0, 0, 0, 0, 0};
	}*/
	return res;
}

컴파일 시 표준 에러 (stderr) 메시지

split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:38:17: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   38 |   while(v.size()<n){
      |         ~~~~~~~~^~
split.cpp:132:5: warning: unused variable 'trycnt' [-Wunused-variable]
  132 |  ll trycnt = 1000;
      |     ^~~~~~
split.cpp: In lambda function:
split.cpp:110:4: warning: control reaches end of non-void function [-Wreturn-type]
  110 |    };
      |    ^
split.cpp: In lambda function:
split.cpp:121:4: warning: control reaches end of non-void function [-Wreturn-type]
  121 |    };
      |    ^
split.cpp: In lambda function:
split.cpp:178:5: warning: control reaches end of non-void function [-Wreturn-type]
  178 |     };
      |     ^
split.cpp: In lambda function:
split.cpp:189:5: warning: control reaches end of non-void function [-Wreturn-type]
  189 |     };
      |     ^
#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...