传送门
题解:
一个显然的结论是最终分裂出来的状态的分裂的中间操作没有关系。
一个朴素的想法是按照两维排序之后扫一遍看是否有缺口。
一个简单的优化是,排序用set,分裂从四个方向搞,每次启发式分裂把小的拿出去。
十分好写,一发AC。
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
namespace IO{
inline char gc(){
static cs int Rlen=1<<22|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>
inline T get(){
char c;T num;bool f=0;
while(!isdigit(c=gc()))f=c=='-';num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return f?-num:num;
}
inline int gi(){return get<int>();}
}
using namespace IO;
using std::cerr;
using std::cout;
struct Point{int x,y;};
struct cmp1{bool operator()(cs Point &a,cs Point &b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}};
struct cmp2{bool operator()(cs Point &a,cs Point &b){return a.y<b.y||(a.y==b.y&&a.x<b.x);}};
typedef std::set<Point,cmp1> Sx;
typedef std::set<Point,cmp2> Sy;
int ans;
inline void split(Sx &s1,Sy &s2){
auto lx=s1.begin(),rx=--s1.end();
auto ly=s2.begin(),ry=--s2.end();
int n=s1.size()>>1;
for(int re i=1;i<=n;++i){
{
auto tp=lx++;
if(tp->x+1<lx->x){
Sx s3;Sy s4;lx=++tp;
for(tp=s1.begin();tp!=lx;){
auto now=tp++;
s3.insert(*now);
s4.insert(*now);
s2.erase(*now);
s1.erase(now);
}
split(s1,s2);split(s3,s4);
return ;
}
}
{
auto tp=rx--;
if(tp->x-1>rx->x){
Sx s3;Sy s4;rx=--tp;
for(tp=--s1.end();tp!=rx;){
auto now=tp--;
s3.insert(*now);
s4.insert(*now);
s2.erase(*now);
s1.erase(now);
}
split(s1,s2);split(s3,s4);
return ;
}
}
{
auto tp=ly++;
if(tp->y+1<ly->y){
Sx s3;Sy s4;ly=++tp;
for(tp=s2.begin();tp!=ly;){
auto now=tp++;
s4.insert(*now);
s3.insert(*now);
s1.erase(*now);
s2.erase(now);
}
split(s1,s2);split(s3,s4);
return ;
}
}
{
auto tp=ry--;
if(tp->y-1>ry->y){
Sx s3;Sy s4;ry=--tp;
for(tp=--s2.end();tp!=ry;){
auto now=tp--;
s4.insert(*now);
s3.insert(*now);
s1.erase(*now);
s2.erase(now);
}
split(s1,s2);split(s3,s4);
return ;
}
}
}++ans;
}
Sx sx;Sy sy;
signed main(){
#ifdef zxyoi
freopen("meta.in","r",stdin);
#endif
int n=gi();
while(n--){
int x=gi(),y=gi();
sx.insert((Point){x,y});
sy.insert((Point){x,y});
}
split(sx,sy);
cout<<ans<<"\n";
return 0;
}