답안 #247054

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
247054 2020-07-10T20:31:04 Z opukittpceno_hhr Drzava (COCI15_drzava) C++17
152 / 160
1000 ms 8180 KB
#ifndef LOCAL
#pragma GCC optimize("Ofast")
// #pragma GCC optimize("unroll-loops")
#endif
 
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <fstream>
#include <cassert>
#include <cstring>
#include <unordered_set>
#include <unordered_map>
#include <numeric>
#include <ctime>
#include <bitset>
#include <complex>
#include <chrono>
#include <random>
#include <functional>
 
using namespace std;
 
typedef long double ld;
 
typedef long long ll;
 
const int N = 5e4;
const int K = 30;
 
int n, k;
int X[N];
int Y[N];
int C[N];
 
int ids[N];
pair<int, int> block[N];
vector<int> by_block[N];
 
int block_ind[N];
int bl_ids[N][3][3]; 
 
int used[N];
 

 
int hv[N];
 
void dfs(int i, int &pnt, ll mid_int) {
	hv[pnt++] = C[i];
	used[i] = 1;
	int we = block_ind[i];
	for (int dx = -1; dx <= 1; dx++) {
		for (int dy = -1; dy <= 1; dy++) {
			int bl_id = bl_ids[we][dx + 1][dy + 1];
			if (bl_id == -1) continue;
			for (auto other : by_block[bl_id]) {
				if (!used[other] && (ll)(X[i] - X[other]) * (X[i] - X[other]) + (ll)(Y[i] - Y[other]) * (Y[i] - Y[other]) <= mid_int) {
					dfs(other, pnt, mid_int);
				}
			}
		}
	}
}
 
int dp[N][K];
 
bool solve(int pnt) {
	fill(dp[0], dp[0] + k, -N);
	dp[0][0] = 0;
	for (int i = 0; i < pnt; i++) {
		fill(dp[i + 1], dp[i + 1] + k, -N);
		for (int j = 0; j < k; j++) {
			if (dp[i][j] == -N) continue;
			dp[i + 1][(j + hv[i]) % k] = max(dp[i + 1][(j + hv[i]) % k], dp[i][j] + 1); 
			dp[i + 1][j] = max(dp[i + 1][j], dp[i][j]);
		}
		if (dp[i + 1][0]) return true;
	}
	return false;
}
 
vector<pair<int, int>> seen;
 
int gt(pair<int, int> v) {
	auto it = lower_bound(seen.begin(), seen.end(), v);
	if (it != seen.end() && *it == v) {
		return (int)(it - seen.begin());
	}
	return (int)-1;
};

bool check(ll mid_int) {
	{
		ld mid = sqrt((ld)mid_int) / 2;
		for (int i = 0; i < n; i++) {
			ids[i] = i;
			block[i] = {X[i] / mid, Y[i] / mid};
		}
		sort(ids, ids + n, [&](int i, int j) {
			return block[i] < block[j];
		});
		for (int i = 0; i < n; i++) {
			int r = i;
			while (r + 1 < n && block[ids[r]] == block[ids[r + 1]]) {
				r++;
			}
			if (r - i + 1 >= k) {
				return true;
			}
			i = r;
		}	
	}
	{
		ld mid = sqrt((ld)mid_int);
		seen.clear();
		for (int i = 0; i < n; i++) {
			ids[i] = i;
			block[i] = {X[i] / mid, Y[i] / mid};
			seen.push_back(block[i]);
			by_block[i].clear();
		}
		sort(ids, ids + n, [&](int i, int j) {
			return block[i] < block[j];
		});
	}
	{
		int c = 0;
		for (int i = 0; i < n; i++) {
			if (i > 0) c += (block[ids[i - 1]] < block[ids[i]]);
			block_ind[ids[i]] = c;
		}
	}
	sort(seen.begin(), seen.end());
	seen.resize(unique(seen.begin(), seen.end()) - seen.begin());
	for (int i = 0; i < (int)seen.size(); i++) {
		for (int dx = -1; dx <= 1; dx++) {
			for (int dy = -1; dy <= 1; dy++) {
				bl_ids[i][dx + 1][dy + 1] = gt({seen[i].first + dx, seen[i].second + dy});
			}
		}
	}
	for (int i = 0; i < n; i++) {
		by_block[gt(block[i])].push_back(i);
	}
	fill(used, used + n, 0);
	for (int i = 0; i < n; i++) {
		if (!used[i]) {
			int pnt = 0;
			dfs(i, pnt, mid_int);
			if (solve(pnt)) return true;
		}
	}
	return false;
}
 
signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	
	cin >> n >> k;
	for (int i = 0; i < n; i++) {
		cin >> X[i] >> Y[i] >> C[i];
	}
	ll r = 4e16 + 239;
	for (int i = 60; i >= 0; i--) {
		if (r > (1LL << i) && check(r - (1LL << i))) r -= (1LL << i);
	}
	cout << fixed << setprecision(3);
	cout << sqrt(r) << endl;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 5 ms 1536 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 5 ms 1536 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 13 ms 1664 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 20 ms 1664 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 10 ms 1664 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 12 ms 1664 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 12 ms 1664 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 18 ms 1664 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 230 ms 3956 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 615 ms 6772 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Execution timed out 1078 ms 6820 KB Time limit exceeded
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 570 ms 6644 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 604 ms 6980 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 598 ms 6952 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 577 ms 7156 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 590 ms 7228 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 508 ms 8052 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 518 ms 8180 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 593 ms 7024 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 1536 KB Output is correct
2 Correct 526 ms 7516 KB Output is correct