【kd-tree】BZOJ4520 CQOI2016K远点对
2016-04-13 13:11
399 查看
传送门
以下是Claris老司机对卡壳错误的证明…(图片来至UOJ用户群…)
ps:当然也可以求k次卡壳,找到最远点对,然后将这两个点到其他所有点的距离放入优先队列,然后删除这两个点…这样做k次就行了…时间复杂度O(kn)O(kn)
由于出题人SB,数据中所有的n>kn>k,然后让某些SB钢了kk(而不是min(n,k)min(n,k))次卡壳就这样过了。
如果这些点组成了一条直线…根本就木有凸包…
你卡壳啊,卡啊…
其实这是一个模板题…
第k远点对肯定在某一个点的前k远距离中…
然后就用kd-tree把某一个点的前k远距离都找出来…
然后再加一些弱弱滴剪枝就可以过辣~(≧▽≦)/~
ps:不就是一个搜索吗╮(╯_╰)╭
当时考试的时候根本不会kd-tree啊…/(ㄒoㄒ)/~~
哭晕在厕所…
附代码…
以下是Claris老司机对卡壳错误的证明…(图片来至UOJ用户群…)
ps:当然也可以求k次卡壳,找到最远点对,然后将这两个点到其他所有点的距离放入优先队列,然后删除这两个点…这样做k次就行了…时间复杂度O(kn)O(kn)
由于出题人SB,数据中所有的n>kn>k,然后让某些SB钢了kk(而不是min(n,k)min(n,k))次卡壳就这样过了。
如果这些点组成了一条直线…根本就木有凸包…
你卡壳啊,卡啊…
其实这是一个模板题…
第k远点对肯定在某一个点的前k远距离中…
然后就用kd-tree把某一个点的前k远距离都找出来…
然后再加一些弱弱滴剪枝就可以过辣~(≧▽≦)/~
ps:不就是一个搜索吗╮(╯_╰)╭
当时考试的时候根本不会kd-tree啊…/(ㄒoㄒ)/~~
哭晕在厕所…
附代码…
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #define LL long long int #define sqr(a) 1ll*(a)*(a) #define MAXN 100005 using namespace std; char w;bool f; inline void GET(int &t) { t=0, f=0; do{w=getchar();if(w=='-')f=1;}while(w<'0'||w>'9'); do{t=t*10+w-'0';w=getchar();}while(w>='0'&&w<='9'); if(f)t=-t; } struct aaa { LL dis; aaa(){} aaa(const LL &a){dis=a;} bool operator < (const aaa &a)const{return dis>a.dis;} }tmp; priority_queue<aaa>q; int Q, n, K; struct node { int d[2]; inline void in(){GET(d[0]), GET(d[1]);} bool operator < (const node &a)const{return d[Q]<a.d[Q];} }p[MAXN], v; LL dist(const node &a,const node &b) {return sqr(a.d[0]-b.d[0])+sqr(a.d[1]-b.d[1]);} struct KD_tree { node val[MAXN]; int root, lc[MAXN], rc[MAXN], minv[MAXN][2], maxv[MAXN][2]; inline void up(int u) { for(int i=0;i<2;++i) { minv[u][i]=maxv[u][i]=val[u].d[i]; if(lc[u])minv[u][i]=min(minv[u][i],minv[lc[u]][i]), maxv[u][i]=max(maxv[u][i],maxv[lc[u]][i]); if(rc[u])minv[u][i]=min(minv[u][i],minv[rc[u]][i]), maxv[u][i]=max(maxv[u][i],maxv[rc[u]][i]); } } LL get(int u) { if(!u)return 0; LL ans=0; for(int i=0;i<2;++i) ans+=max(sqr(minv[u][i]-v.d[i]),sqr(maxv[u][i]-v.d[i])); return ans; } int build(int l,int r,int k) { if(l>r)return 0; int mid=(l+r)>>1; Q=k; nth_element(p+l,p+mid,p+r+1); val[mid]=p[mid]; lc[mid]=build(l,mid-1,k^1); rc[mid]=build(mid+1,r,k^1); up(mid); return mid; } void query(int u) { if(!u)return; LL dl=get(lc[u]), dr=get(rc[u]), d=dist(v,val[u]); if(d>q.top().dis)q.pop(), q.push(aaa(d)); if(dl>dr) { if(dl>q.top().dis)query(lc[u]); if(dr>q.top().dis)query(rc[u]); } else { if(dr>q.top().dis)query(rc[u]); if(dl>q.top().dis)query(lc[u]); } } }t; int main() { GET(n), GET(K); for(int i=1;i<=n;++i)p[i].in(); t.root=t.build(1,n,0); for(int i=0;i<K+K;++i)q.push(tmp); for(int i=1;i<=n;++i) { v=p[i]; t.query(t.root); } cout<<q.top().dis; return 0; }
相关文章推荐
- iOS隐藏一个View(定时器)
- 在Inspectable 中编辑view 属性
- 解决android studio模拟器“is currently running"的方法
- View绘制尚未完成,getHeight=0
- ListView 卡顿的原因
- 依赖倒置原则
- iOS UILabel详解
- Android自定义View — 用Canvas画带动画的渐变数字圆环
- 面向对象方式解决比赛名单类问题(Java实现)
- VideoView (Vitamioplayer使用)播放网络视频
- 新硬盘-安装Fedora23
- 第七周项目(1)-友员函数求两点间距离
- android webview js alert对话框 不能弹出 解决办法
- iPhone4/4s运行iOS7慢怎么办
- android中xml tools属性详解
- PHP session 失效不传递的解决办法
- Memcache的最佳实践方案
- iOS开发之Xcode pch头文件简单使用方法 让写代码更简单!
- 主动通知Android系统图库进行更新
- adb server无法启动方法,结束占用端口的进程