KD_Tree再写
Insert就是垃圾!!!!!!以后只要不是强制在线就算死也不用这个辣鸡玩意儿!!!!
#include<bits/stdc++.h> #define ll long long using namespace std; int n,k,cnt; namespace KD_Tree { int dim; priority_queue<ll,vector<ll>,greater<ll> >q; void mdf(ll x){q.push(x);q.pop();} struct Point { ll P[2]; int ls,rs; ll mn[2],mx[2]; }c[100010]; bool cmp(Point a,Point b){return a.P[dim]<b.P[dim];} ll sqr(ll x) {return x*x;} ll calc(Point x,Point y){return sqr(x.P[0]-y.P[0])+sqr(x.P[1]-y.P[1]);} void update(int x) { c[x].mn[0]=c[x].mx[0]=c[x].P[0]; c[x].mn[1]=c[x].mx[1]=c[x].P[1]; for(int i=0;i<2;i++) { if(c[x].ls) { c[x].mn[i]=min(c[x].mn[i],c[c[x].ls].mn[i]); c[x].mx[i]=max(c[x].mx[i],c[c[x].ls].mx[i]); } if(c[x].rs) { c[x].mn[i]=min(c[x].mn[i],c[c[x].rs].mn[i]); c[x].mx[i]=max(c[x].mx[i],c[c[x].rs].mx[i]); } } } int build(int l,int r,int w) { if(l>r) return 0; if(l==r) {update(l);return l;} dim=w;int mid=(l+r)>>1; nth_element(c+l,c+mid,c+r+1,cmp); c[mid].ls=build(l,mid-1,w^1);c[mid].rs=build(mid+1,r,w^1); update(mid); return mid; } ll cheque(int x,Point p) { ll tx=max(sqr(c[x].mn[0]-p.P[0]),sqr(c[x].mx[0]-p.P[0])); ll ty=max(sqr(c[x].mn[1]-p.P[1]),sqr(c[x].mx[1]-p.P[1])); return tx+ty; } void qury(int x,Point p) { ++cnt; mdf(calc(c[x],p)); ll dl=0,dr=0; if(c[x].ls) dl=cheque(c[x].ls,p); if(c[x].rs) dr=cheque(c[x].rs,p); if(dl>dr) { if(dl>q.top()) qury(c[x].ls,p); if(dr>q.top()) qury(c[x].rs,p); } else { if(dr>q.top()) qury(c[x].rs,p); if(dl>q.top()) qury(c[x].ls,p); } } } using namespace KD_Tree; int main() { freopen("3.in","r",stdin); scanf("%d%d",&n,&k); for(int i=1;i<=2*k;i++) q.push(0); for(int i=1;i<=n;i++) { scanf("%lld%lld",&c[i].P[0],&c[i].P[1]); } int rt=build(1,n,0); for(int i=1;i<=n;i++) { qury(rt,c[i]); } printf("%lld\n",q.top()); cout<<cnt<<endl; }
lunatic太难辣!!!!!