Editorial for Mini Multiverse
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
#include <iostream>
#include <algorithm> //using sort
#include <vector>
#include <cstdio>
#include <cmath>
using namespace std;
#define ll long long
struct Point{
ll x,y;
void input(){
cin>>x>>y;
x=abs(x);
y=abs(y);
}
};
Point arr[1000000];
bool compareX(Point a, Point b){
return a.x<b.x;
}
bool compareY(Point a, Point b){
return a.y<b.y;
}
ll dist(Point a,Point b){
return abs(a.x-b.x)+abs(a.y-b.y);
}
// only takes n=2 or n=3
ll base_case(Point *points, int n){
ll minDist=dist(points[0],points[1]);
if(n==3){
ll dist2=dist(points[0],points[2]);
ll dist3=dist(points[2],points[1]);
minDist=min(minDist,min(dist2,dist3));
}
return minDist;
}
ll recursive_solve(Point *points, int n){
if (n < 4) //since 3 would
return base_case(points, n);
int mid = n / 2;
ll minLeft = recursive_solve(points, mid);
ll minRight = recursive_solve(points+mid, n-mid);
ll minDist = min(minLeft, minRight);
//O(n) here could be more optimal (by checking from mid to edges) but its already under bounding complexity and worst case doesn't change
//O(nlogn) in total
vector<Point> additional;
for (int i=0; i < n; i++){
if (abs(points[i].x - points[mid].x) < minDist)
additional.push_back(points[i]);
}
// O(nlogn) here
//O(nlognlogn) in total
sort(additional.begin(), additional.end(), compareY);
// O(n) because inner loop is actually constant
// O(nlogn) in total
for (int i=0;i<additional.size();i++) {
//this looks like O(n) but it comes up to constant(at most 5)
for (int j=i+1;j<additional.size() && (additional[j].y-additional[i].y)<minDist; j++){
minDist = min(minDist, dist(additional[i], additional[j]));
}
}
return minDist;
}
// Complexity Calculation
// nlogn = nlogn
// 2*n/2log(n/2) = nlogn-n
// 4*n/4log(n/4) = nlogn-2n
// 8*n/8log(n/8) = nlogn-3n
// ...
// ...
// ...
// (n/2)*n/(n/2)log(n/(n/2)) = nlogn-logn*n
// nlogn*logn-n*logn*(logn-1)/2
// nlogn*(logn+1)/2
// O(nlognlogn)
int main(){
ll n;
cin>>n;
for(int i=0;i<n;i++)arr[i].input();
sort(arr,arr+n,compareX);
cout<<recursive_solve(arr,n)<<endl;
}