BZOJ4520: [Cqoi2016]K远点对

一开始打的二分答案QWQ
后来发现T了
只好暴力了QAQ

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
#define ull unsigned long long
bool flag;
char c;
inline void read(ll &a)
{

    a=0;do c=getchar();while(c!='-'&&(c<'0'||c>'9'));
    if(c=='-')c=getchar(),flag=true;
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
    if(flag)a=-a,flag=false;
}
struct S
{
    ull l;
    inline friend bool operator <(S a,S b){return a.l>b.l;}
};
ll op;
struct Point
{
  ll x[2];
  inline ll & operator[](ll X)
  {return x[X];}
}P[100001];
struct KD
{
    ll size;
    ll op;
    Point x;
    ll Min[2],Max[2];
    KD *lc,*rc;
};

inline bool operator <(Point a,Point b)
{return a[op]<b[op];}
ull Mid;
priority_queue<S>Q;

KD* Build (ll l,ll r)
{
    if(r<l)return NULL;
    if(l==r)
    {
     KD *E=new KD;
     E->x=P[l];
     E->size=1;
     E->op=1;
     E->Min[0]=E->Max[0]=E->x[0];
     E->Min[1]=E->Max[1]=E->x[1];
     E->lc=E->rc=NULL;
     return E;
    } 
    ll mid=l+r>>1;
    ll t1,t2,flag,Ave;
    op=1;
    Ave=t1=0;
    for(ll i=l;i<=r;i++)Ave+=P[i][op];
    Ave/=r-l+1;
    for(ll i=l;i<=r;i++)t1+=(Ave-P[i][op])*(Ave-P[i][op]);
    op=0;
    Ave=t2=0;
    for(ll i=l;i<=r;i++)Ave+=P[i][op];
    Ave/=r-l+1;
    for(ll i=l;i<=r;i++)t2+=(Ave-P[i][op])*(Ave-P[i][op]);
    op=t2>t1?0:1;
    sort(P+l+1,P+r+1);
     KD *E=new KD;
     E->x=P[mid];
     E->size=r-l+1;
     E->op=1;
     E->Min[0]=E->Max[0]=E->x[0];
     E->Min[1]=E->Max[1]=E->x[1];
     E->lc=Build(l,mid-1),E->rc=Build(mid+1,r);
     E->Min[0]=min(E->Min[0],E->lc==NULL?1<<29:E->lc->Min[0]);
     E->Min[1]=min(E->Min[1],E->lc==NULL?1<<29:E->lc->Min[1]);
     E->Min[0]=min(E->Min[0],E->rc==NULL?1<<29:E->rc->Min[0]);
     E->Min[1]=min(E->Min[1],E->rc==NULL?1<<29:E->rc->Min[1]);
     E->Max[0]=max(E->Max[0],E->lc==NULL?-1<<29:E->lc->Max[0]);
     E->Max[1]=max(E->Max[1],E->lc==NULL?-1<<29:E->lc->Max[1]);
     E->Max[0]=max(E->Max[0],E->rc==NULL?-1<<29:E->rc->Max[0]);
     E->Max[1]=max(E->Max[1],E->rc==NULL?-1<<29:E->rc->Max[1]);
     return E;
}
ll Cur_;
ll K;
Point O;

void Query(KD*Cur)
{
    if(Cur==NULL)return;
    ll Mx[2],Mn[2];
    Mx[1]=max(abs(O[1]-Cur->Min[1]),abs(Cur->Max[1]-O[1]));
    Mx[0]=max(abs(O[0]-Cur->Min[0]),abs(Cur->Max[0]-O[0]));
    Mn[1]=min(abs(O[1]-Cur->Min[1]),abs(Cur->Max[1]-O[1]));
    Mn[0]=min(abs(O[0]-Cur->Min[0]),abs(Cur->Max[0]-O[0]));
    if(Cur->Min[0]<=O[0]&&Cur->Max[0]>=O[0])Mn[0]=0;
    if(Cur->Min[1]<=O[1]&&Cur->Max[1]>=O[1])Mn[1]=0;
    if(Cur_>=K)return ;
    S E=Q.top();
    //if(Mid<Mn[0]*1ull*Mn[0]+Mn[1]*1ull*Mn[1])
        //{Cur_+=Cur->size;return;}
     ull tpp;
    if(Q.top().l<(tpp=(Cur->x[0]-O[0])*1ull*(Cur->x[0]-O[0])+(Cur->x[1]-O[1])*1ull*(Cur->x[1]-O[1])))
        Q.pop(),Q.push((S){tpp});
    if(Q.top().l<Mx[0]*1ull*Mx[0]+Mx[1]*1ull*Mx[1])
    {
      Query(Cur->lc);
      if(Cur_>=K)return ;
       Query(Cur->rc);
     }
}




const
  ull INF=-1;
int main()
{
    ll n;
    read(n),read(K);
    for(ll i=1;i<=n;i++)
         read(P[i][0]),read(P[i][1]);
    KD*Ry=Build(1,n);
    ull ans,L=0,R=INF;
    K*=2;
    for(int i=1;i<=K;i++)
    Q.push((S){0});

    Cur_=0;
    for(ll i=1;i<=n;i++)
        {
          O=P[i];
          if(Cur_>=K)break;
          Query(Ry);
        }
    cout<<Q.top().l<<endl;
    return 0;
}

你可能感兴趣的:(BZOJ4520: [Cqoi2016]K远点对)