LibreOJ2043 - 「CQOI2016」K 遠點對
阿新 • • 發佈:2018-05-26
targe prior vector line std tar 比較 namespace for
Portal
Description
給出平面上的\(n(n\leq10^5)\)個整點,求在歐幾裏得距離下第\(k\)遠的點對之間的距離。
Solution
k-d樹+堆。
用小根堆維護當前找到的第\(k\)大,然後以堆頂元素為基準在k-d樹上搜索即可。搜索到一個新值\(d\)時,將其與堆頂元素比較,若大於堆頂元素則彈出堆頂並加入\(d\)。
Code
//「CQOI2016」K 遠點對
#include <algorithm>
#include <cstdio>
#include <queue>
typedef long long lint;
using namespace std;
inline char gc()
{
static char now[1<<16],*s,*t;
if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
return *s++;
}
inline int read()
{
int x=0; char ch=gc();
while(ch<'0'||'9'<ch) ch=gc();
while('0'<=ch&&ch<='9' ) x=x*10+ch-'0',ch=gc();
return x;
}
const int N=1e5+10;
const int INF=0x3FFFFFFF;
int n,k;
int rt,ch[N][2];
struct point{int c[2];} pt[N];
struct zone{int c1[2],c2[2];} zn[N];
void update(int p)
{
int ch0=ch[p][0],ch1=ch[p][1];
for(int k=0;k<2;k++)
zn[p].c1[k]=min(pt[p].c[k],min(zn[ch0].c1[k],zn[ch1].c1[k])),
zn[p].c2[k]=max(pt[p].c[k],max(zn[ch0].c2[k],zn[ch1].c2[k]));
}
int D;
bool operator<(point A,point B) {return A.c[D]<B.c[D];}
void bldTr(int &p,int L,int R)
{
if(L>R) return;
int mid=L+R>>1; p=mid;
nth_element(pt+L,pt+mid,pt+R+1);
bldTr(ch[p][0],L,mid-1),bldTr(ch[p][1],mid+1,R);
update(p);
}
priority_queue< lint,vector<lint>,greater<lint> > Q;
point A;
lint dist(point B)
{
lint d=0;
for(int k=0;k<2;k++) d+=1LL*(A.c[k]-B.c[k])*(A.c[k]-B.c[k]);
return d;
}
lint dist(zone Z)
{
if(Z.c1[0]>Z.c2[0]) return 0;
int d[2]; d[0]=d[1]=0;
for(int k=0;k<2;k++) d[k]=max(abs(Z.c1[k]-A.c[k]),abs(Z.c2[k]-A.c[k]));
return 1LL*d[0]*d[0]+1LL*d[1]*d[1];
}
void query(int p)
{
if(!p) return;
lint d=dist(pt[p]);
if(d>Q.top()) Q.pop(),Q.push(d);
lint d0=dist(zn[ch[p][0]]),d1=dist(zn[ch[p][1]]);
if(d0>Q.top()) query(ch[p][0]);
if(d1>Q.top()) query(ch[p][1]);
}
int main()
{
n=read(),k=read();
for(int i=1;i<=n;i++) pt[i].c[0]=read(),pt[i].c[1]=read();
zn[0].c1[0]=zn[0].c1[1]=INF,zn[0].c2[0]=zn[0].c2[1]=-INF;
bldTr(rt,1,n);
for(int i=1;i<=k+k;i++) Q.push(0);
for(int i=1;i<=n;i++) A=pt[i],query(rt);
printf("%d\n",Q.top());
return 0;
}
P.S.
網上好多題解是凸包+旋轉卡殼...嚇死我了∑(?Д?ノ)ノ
LibreOJ2043 - 「CQOI2016」K 遠點對