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;

}


 

 

你可能感兴趣的:(play)