zoukankan      html  css  js  c++  java
  • BZOJ 1941 kd-tree

    模板题 题意说的可能有点不清楚 一开始的点必须在给定的n个点里面

    所以枚举点 然后ask最大和最小值

    估价函数中 最大值的写法和最小值不同 全部取max

    而最小值在估价时 如果在某个点管辖的空间里 就视为距离=0

    估价函数如果写错 可能会导致wa or t

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<math.h>
    #include<queue>
    #include<string>
    using namespace std;
    #define L long long
    const int INF = 999999999 ;
    int n , root , cmp_d ;
    struct node{
        int d[2] , Max[2] , Min[2];
        int l , r ;
    }a[500050] ;
    bool cmp(node a,node b){
        return ((a.d[cmp_d] < b.d[cmp_d]) || (a.d[cmp_d] == b.d[cmp_d] && a.d[!cmp_d] < b.d[!cmp_d])) ;
    }
    void up(int p , int k ){
        a[p].Max[0] = max(a[p].Max[0] , a[k].Max[0]);
        a[p].Max[1] = max(a[p].Max[1] , a[k].Max[1]);
        a[p].Min[0] = min(a[p].Min[0] , a[k].Min[0]);
        a[p].Min[1] = min(a[p].Min[1] , a[k].Min[1]);
    }
    int build(int l, int r , int  D )  {
        int mid = (l+r) >> 1 ;
        cmp_d = D;
        nth_element(a+1+l,a+1+mid,a+1+r,cmp) ;
        a[mid].Max[0] = a[mid].Min[0] = a[mid].d[0];
        a[mid].Max[1] = a[mid].Min[1] = a[mid].d[1];
        if(l != mid)
            a[mid].l = build(l,mid-1,D^1);
        else a[mid].l = 0 ;
        if(r != mid)
            a[mid].r = build(mid+1,r,D^1);
        else a[mid].r = 0 ;
        if(a[mid].l)up(mid,a[mid].l);
        if(a[mid].r)up(mid,a[mid].r);
        return mid ;
    }
    int ans1 , ans2 ;
    int x, y ;
    int getMaxdis(int p) {
        int res = 0 ;
        res += max(max(x - a[p].Max[0] , a[p].Max[0] - x) , max(x - a[p].Min[0] , a[p].Min[0] - x)) ;
        res += max(max(y - a[p].Max[1] , a[p].Max[1] - y) , max(y - a[p].Min[1] , a[p].Min[1] - y)) ;
        return res ;
    }
    void query_Max(int p) {
        int d0 ;
        int dl,dr ;
        d0 = abs(x - a[p].d[0]) + abs(y - a[p].d[1]) ;
        if(d0 != 0) {
            ans2 = max(ans2 , d0) ;
        }
        if(a[p].l)
            dl = getMaxdis(a[p].l) ;
        else dl = -INF ;
        if(a[p].r)
            dr = getMaxdis(a[p].r) ;
        else dr = -INF ;
        if(dl > dr) {
            if(dl > ans2)query_Max(a[p].l) ;
            if(dr > ans2)query_Max(a[p].r) ;
        }
        else {
            if(dr > ans2)query_Max(a[p].r) ;
            if(dl > ans2)query_Max(a[p].l) ;
        }
    }
    int getMindis(int p) {
        int res = 0 ;
        if(x > a[p].Max[0]) res += x - a[p].Max[0] ;
        if(x < a[p].Min[0]) res += a[p].Min[0] - x ;
        if(y > a[p].Max[1]) res += y - a[p].Max[1] ;
        if(y < a[p].Min[1]) res += a[p].Min[1] - y ;
        return res ;
    }
    void query_Min(int p) {
        int d0 , dl , dr ;
        d0 = abs(a[p].d[0] - x) + abs(a[p].d[1] - y) ;
        if(d0 != 0) {
            ans1 = min(d0 , ans1) ;
        }
        if(a[p].l)
            dl = getMindis(a[p].l) ;
        else dl = INF ;
        if(a[p].r)
            dr = getMindis(a[p].r) ;
        else dr = INF ;
        if(dl < dr) {
            if(dl < ans1)query_Min(a[p].l) ;
            if(dr < ans1)query_Min(a[p].r) ;
        }
        else {
            if(dr < ans1)query_Min(a[p].r) ;
            if(dl < ans1)query_Min(a[p].l) ;
        }
    }
    int main(){
        int n ;
        scanf("%d",&n);
        for(int i = 1; i <= n ; i ++ ){
            scanf("%d%d",&a[i].d[0],&a[i].d[1]) ;
        }
        root = build(1,n,0) ;
        int ans = INF ;
        for(int i = 1; i <= n ; i ++ ){
            ans1 = INF , ans2 = -INF ;
            x = a[i].d[0] , y = a[i].d[1] ;
            query_Max(root) ;
            query_Min(root) ;
            ans = min(ans , ans2 - ans1) ;
        }
        printf("%d
    ",ans) ;
    }
    

      

  • 相关阅读:
    SVN
    Oracle用户、权限、角色管理(转)
    X5学习笔记—给单元格添加颜色
    JdbcTemplae使用入门&&Spring三种连接池配置&&Spring配置文件引用外部properties文件
    依赖注入Bean属性
    IoC容器装配Bean(xml配置方式)(Bean的生命周期)
    Spring配置文件的读取
    Spring IoC反转控制的快速入门
    spring security 权限框架原理
    win7 开机,或重启自动启动 该文件下的
  • 原文地址:https://www.cnblogs.com/rayrayrainrain/p/6351650.html
Copyright © 2011-2022 走看看