Submission #252852

#TimeUsernameProblemLanguageResultExecution timeMemory
252852user202729Circle selection (APIO18_circle_selection)C++17
64 / 100
3106 ms185188 KiB
// not sure what's the bottleneck
#ifndef LOCAL
#define NDEBUG 1
#endif
#include<bits/stdc++.h>

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);

	using Index=int; // for circles
	struct Circle{
		int x, y, r;
		bool intersect(Circle other) const{
			assert(r>0); assert(other.r>0);
			return int64_t(x-other.x)*(x-other.x)+int64_t(y-other.y)*(y-other.y)<=
				int64_t(r+other.r)*(r+other.r);
		}
	};
	int number; std::cin>>number;
	std::vector<Circle> circles(number);
	for(auto& [x, y, r]: circles)
		std::cin>>x>>y>>r; // r==0: deleted

	struct A{
		Index index; int r;
		bool operator<(A other) const{
			return r!=other.r ? r<other.r: index>other.index;
		}
	};
	std::priority_queue<A> q;
	for(Index index=0; index<number; ++index)
		q.push({index, circles[index].r});

	auto const callRange=[&](auto& object, int first, int last, auto function){
		auto iterator=object.lower_bound(first);
		while(iterator!=object.end() and iterator->first<last){
			function(iterator->second);
			++iterator;
		}
	};

	std::vector<int> result(number);
	assert((result.assign(number, -1), true));

	std::map<int, std::map<int, std::vector<Index>>> grid;

	int step=30;
	for(Index index=0; index<number; ++index){
		auto const [x, y, r]=circles[index];
		assert(r>0); assert(r<(1<<step));
	
		grid[x>>step][y>>step].push_back(index);
	}

	for(; step;--step){
		auto oldGrid=std::move(grid);
		grid.clear();

		for(auto const& [a, it]: oldGrid)
			for(auto const& [b, indices]: it){
				std::array<std::array<std::vector<Index>, 2>, 2> parts;
				for(auto const index: indices){
					auto [x, y, r]=circles[index];
					assert(r>0);
					assert((x>>(step+1))==a);
					assert((y>>(step+1))==b);
					parts[x>>step&1][y>>step&1].push_back(index);
				}
				for(int x=0; x<2; ++x){
					auto& tmp=grid[a<<1|x];
					for(int y=0; y<2; ++y) if(not parts[x][y].empty())
						tmp[b<<1|y]=std::move(parts[x][y]);
				}
			}

		/*
		grid.clear();
		for(Index index=0; index<number; ++index){
			auto const [x, y, r]=circles[index];
			if(r==0) continue;
			assert(r<(1<<step));
		
			grid[x>>step][y>>step].push_back(index);
		}
		*/

		while(true){
			if(q.empty())
				goto break_outer;

			auto [index, r_]=q.top();
			auto const cur=circles[index]; auto const [x, y, r]=cur;
			if(r==0) {
				q.pop();
				continue;
			}
			assert(r==r_);
			if(r<((1<<step)>>1))
				break; // goto next step -- without popping from q

			q.pop();
			circles[index].r=0;

			assert(result[index]==-1); result[index]=index;
			callRange(grid, (x>>step)-2, (x>>step)+3, [&](auto& it){
				callRange(it, (y>>step)-2, (y>>step)+3, [&](auto& it){
					it.erase(std::remove_if(begin(it), end(it), [&](Index index1){
						if(index1==index){
							return true;
						}

						auto& cur1=circles[index1];
						assert(cur1.r>0);
						if(cur1.intersect(cur)){
							assert(result[index1]==-1);
							result[index1]=index;
							cur1.r=0;
							return true;
						} else return false;
					}),it.end());
				});
			});
		}
	}
break_outer:

	for(Index index=0; index<number; ++index){
		auto const [x, y, r]=circles[index];
		assert(result[index]!=-1);
		assert(r==0);
	}

	for(auto it: result) std::cout<<it+1<<' ';
	std::cout<<'\n';
}

Compilation message (stderr)

circle_selection.cpp: In function 'int main()':
circle_selection.cpp:49:22: warning: unused variable 'r' [-Wunused-variable]
   auto const [x, y, r]=circles[index];
                      ^
circle_selection.cpp:63:19: warning: unused variable 'r' [-Wunused-variable]
      auto [x, y, r]=circles[index];
                   ^
circle_selection.cpp:91:19: warning: unused variable 'r_' [-Wunused-variable]
    auto [index, r_]=q.top();
                   ^
circle_selection.cpp:128:22: warning: unused variable 'x' [-Wunused-variable]
   auto const [x, y, r]=circles[index];
                      ^
circle_selection.cpp:128:22: warning: unused variable 'y' [-Wunused-variable]
circle_selection.cpp:128:22: warning: unused variable 'r' [-Wunused-variable]
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...