您的位置:首页 > 其它

BZOJ4520: [Cqoi2016]K远点对

2016-04-15 15:39 253 查看
一开始打的二分答案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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: