hdu 1007 最近点对问题(Splay解法)
为什么要写这个题、、经典啊,当然,别以为我用分治做的,不过主要思想还是那神奇的六个点共存(一个h*2h的矩形中最多能放下多少个点使得两两距离不超过h)
其实我是在这里看到的
http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lineSweep
排个序,然后扫描过去,每次确定Y的范围,暴力找每个点(其实这是O(1)的)
蛮不错的哦。
写完后发现比分治写的快了好多啊,估计是我不会写分治吧T_T,总之,现在跑到了rank 4了。。。
数据结构就是这样的直接啊!
/* ********************************************** Author : wuyiqi Created Time: 2013-8-24 12:54:35 File Name : ruocai.cpp *********************************************** */ #include <cstdio> #include <cmath> #include <stack> #include <algorithm> using std::stack; using std::pair; using std::make_pair; #define L x->c[0] #define R x->c[1] #define KT root->c[1]->c[0] const int maxn = 200010; struct node{ node *c[2] , *fa; int id,sz; double val,x; inline bool d() { return fa->c[0] == this; } inline void setc(int d,node *s) { c[d] = s; s->fa = this; } inline void up() { sz = c[0]->sz + c[1]->sz + 1; } }NODE[maxn],*null=&NODE[0]; node *ID[maxn]; int top; struct Splay_tree{ node *root; void Rotate(node *x,int f){ node *y = x->fa; y->setc(!f,x->c[f]); x->fa = y->fa; if(y->fa != null) y->fa->setc(!y->d(),x); x->setc(f,y); y->up(); } void Splay(node *x,node *goal) { while(x->fa!=goal) { if(x->fa->fa == goal) Rotate(x,x->d()); else { int f = x->fa->d(); x->d() == f ? Rotate(x->fa,f) : Rotate(x,!f); Rotate(x,f); } } x->up(); if(goal == null) { root = x; } } void RTO(int k,node *goal) { node *x = root; while(L->sz + 1 != k) { if(k < L->sz + 1) x = L; else { k -= L->sz + 1; x = R; } } Splay(x,goal); } void insert(node* &x,node *y) { if(x == null) { x = y; return ; } if(y->val <= x->val) { insert(x->c[0],y); x->c[0]->fa = x; } else { insert(x->c[1],y); x->c[1]->fa = x; } x->up(); } node* new_node(int id,double x,double y) { node* tmp = &NODE[++top]; tmp->fa = null; tmp->val = y; tmp->x = x; tmp->sz = 1; tmp->id = top; tmp->c[0] = tmp->c[1] = null; ID[id] = tmp; return tmp; } void insert(int id,double x,double y) { node *tmp = new_node(id,x,y); insert(root,tmp); } void init() { root = null; } void Del_root() { node *t = root; if(t->c[1] != null) { root = t->c[1]; RTO(1,null); root->c[0] = t->c[0]; if(root->c[0] != null) root->c[0]->fa = root; } else { root = root->c[0]; } root->fa = null; if(root != null) root->up(); } void Del(node *tmp) { Splay(tmp,null); Del_root(); } node* find_pre(node *x,double v) { if(x == null) return null; if(x->val < v) { node *tmp = find_pre(x->c[1],v); return tmp == null ? x : tmp; } else { return find_pre(x->c[0],v); } } node* find_succ(node *x,double v) { if(x == null) return null; if(x->val > v ) { node *tmp = find_succ(x->c[0],v); return tmp == null ? x : tmp; } else { return find_succ(x->c[1],v); } } void search(double a,double b,double &ans,node* x){ if(x == null) return ; double c = x->x , d = x->val; double cost = sqrt((a-c)*(a-c) + (b-d)*(b-d)); if(cost < ans) ans = cost; if(x->c[0] != null) search(a,b,ans,x->c[0]); if(x->c[1] != null) search(a,b,ans,x->c[1]); } void gao(double x,double y,double &ans) { node *pre = find_pre(root,y-ans) ; node *succ = find_succ(root,y+ans); if(pre == null || succ == null) while(1); Splay(pre,null); Splay(succ,root); search(x,y,ans,KT); } void vist(node *x) { if(x!=null) { printf("%d x = %lf y = %lf lson=%d rson=%d\n",x->id,x->x,x->val,x->c[0]->id,x->c[1]->id); if(x->c[0]!=null) vist(x->c[0]); if(x->c[1]!=null) vist(x->c[1]); } } void debug(){ puts("*******"); vist(root); puts("*****"); } }spt; void prepare() { null->id = 0; null->c[0] = null->c[1] = null->fa = NULL; null->sz = null->val = 0; top = 0; } double x[maxn] , y[maxn]; bool by_x(int a,int b) { return x[a] > x[b]; } int id[maxn]; double sqr(double a) { return a * a; } int main() { int n; while(scanf("%d",&n),n) { prepare(); spt.init(); for(int i = 0; i < n; i++) { id[i] = i; scanf("%lf%lf",&x[i],&y[i]); } if(n == 1){ puts("0.00"); continue; } std::sort(id,id+n,by_x); spt.insert(0,-1e100,-1e100); spt.insert(0,-1e100,1e100); double ans = 1e50 ; int pt = 0; for(int i = 0; i < n; i++) { if(ans == 0) break; while(pt < i && x[id[pt]] > x[id[i]] + ans ) { if(spt.root->sz == 2) break; spt.Del(ID[id[pt]]); pt++; } if(spt.root->sz == 2) { spt.insert(id[i],x[id[i]],y[id[i]]); } else { spt.gao(x[id[i]],y[id[i]],ans); spt.insert(id[i],x[id[i]],y[id[i]]); } } printf("%.2f\n",ans*0.5); } return 0; }