• 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
    ",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
    ",ans*0.5);
        }
        return 0;
    }
    


  • 相关阅读:
    angular面试记忆的内容
    doctype
    161214、oracle查询表信息
    161213、Maven资源替换和Freemarker模板
    161212、并发编程中的关于队列
    161209、简要分析ZooKeeper基本原理及安装部署
    161208、Java enum 枚举还可以这么用
    161207、高并发:java.util.concurrent.Semaphore实现字符串池及其常用方法介绍
    161206、 Ionic、Angularjs、Cordova搭建Android开发环境
    161205、win10安装mysql5.7.16数据库
  • 原文地址:https://www.cnblogs.com/riskyer/p/3279713.html
Copyright © 2020-2023  润新知