又一次产生了KDTree本质就是爆搜的感觉……
大概就类似于,只不过是从最近点对变成了第\(k\)远点对 我们开一个小根堆,里面放\(k\)个元素,起初全为\(0\),然后每一次都把点对的距离和堆顶比较,如果点对距离大于就弹出堆顶并让这个点对入堆,那么最后堆顶就是答案了 于是我们可以枚举每一个点,然后在KDTree上dfs就行了 然后因为每个点对会被枚举两次,所以小根堆的大小实际上要开\(2*k\)//minamoto#include#define R register#define ll long long#define inf 0x3f3f3f3f#define fp(i,a,b) for(R int i=a,I=b+1;i I;--i)#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)template inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}template inline bool cmax(T&a,const T&b){return a '9'||ch<'0')(ch=='-')&&(f=-1); for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0'); return res*f;}const int N=1e5+5;struct node{ll v[2],mn[2],mx[2];int l,r;}tr[N],S;int n,m,K,rt;priority_queue ,greater >q;inline bool operator <(const node &a,const node &b){return a.v[K] >1;nth_element(tr+l,tr+mid,tr+r+1); if(l q.top())q.pop(),q.push(dd); if(dl>dr){ if(dl>q.top())query(tr[p].l); if(dr>q.top())query(tr[p].r); }else{ if(dr>q.top())query(tr[p].r); if(dl>q.top())query(tr[p].l); }}int main(){// freopen("testdata.in","r",stdin); n=read(),m=read();fp(i,1,n)tr[i].v[0]=read(),tr[i].v[1]=read(); rt=build(1,n,0);fp(i,1,m*2)q.push(0); fp(i,1,n)S.v[0]=tr[i].v[0],S.v[1]=tr[i].v[1],query(rt); printf("%lld\n",q.top());return 0;}