KD-tree theme "Hide and Seek · Chocolate Kingdom"

Lockey blind understanding

  Copied it and the board both the water problem, we feel a little understanding of the KD-tree a little, nagging about the (two-dimensional KD-tree), if wrong, please point out (Lockey wash respectfully listen)

  Ordinary maintenance of balanced tree is a sequence of one-dimensional, but the two-dimensional (balanced tree can be built balanced tree cover, but poor maintenance) and even multi-dimensional on the cold, so we used the KD-tree data structure of this magical (camouflage "brick house" ing ~)

  KD-tree respectively two-dimensional plane of x, y turns divided to a plane built the BST, and then look for, maintaining the current value of the representative point in the tree and recording information in its subtree rooted (maximum value, minimum value, and the like),

And we can determine whether you need to go through the information currently points down, in order to find the statistics, of course, this judgment conditions must be correct (100% guaranteed not to go down or need to go down)

  In order to optimize time, KD-tree pruning is also more important in such statistics to the maximum, we can estimate the valuation point two sons with valuation function to compare two sons, walking valuation comparison-old son, so , and other son back to come back, the maximum value is likely to be updated, making the original larger than the original and the other son of the maximum can go, now less than the current maximum value can not go, in order to achieve pruning

Hide and Seek (Chinese name: Hide and Seek)

KD-tree board issues a

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,maximum,minimum,sz,now,ans;
struct Point{
    int x[2];
}sour[510000];
int comp(Point a,Point b){
    return a.x[now]<b.x[now];
}
int dis(Point a,Point b){
    return abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1]); 
}
struct{KD_Tree 
    KD_Tree * ch [ 2 ]; 
    Point Ponit; 
    you maxn [ 2 ], from [ 2 ];
    void redef (Point a) { 
        Ponit = a, a [ 0 ] = maxn [ 0 ] = ax [ 0 ], a [ 1 ] = maxn [ 1 ] = ax [ 1 ], ch [ 0 ] = ch [ 1 ] = NULL; 
    } 
    Void update (KD_Tree * a) { 
        a [ 0 ] = min (a [ 0 ], a-> a [ 0 ]), maxn [ 0 ] = max (maxn [0],a->maxn[0]);
        minn[1]=min(minn[1],a->minn[1]),maxn[1]=max(maxn[1],a->maxn[1]);
    }
    void pushup(){
        if(ch[0]) update(ch[0]);
        if(ch[1]) update(ch[1]);
    }
    int calc_min(Point a){
        return max(minn[0]-a.x[0],0)+max(a.x[0]-maxn[0],0)+max(minn[1]-a.x[1],0)+max(a.x[1]-maxn[1],0);
    }
    int calc_max(Point a){
        return max(abs(a.x[0]-minn[0]),abs(a.x[0]-maxn[0]))+max(abs(a.x[1]-minn[1]),abs(a.x[1]-maxn[1]));
    }
}*root,tr[510000];
void build(KD_Tree *&p,int l,int r,int d){
    if(l>r) return;
    p=tr+(sz++),now=d;
    nth_element(sour+l,sour+((l+r)/2),sour+(r+1),comp);
    p->redef(sour[((l+r)/2)]);
    build(p->ch[0],l,((l+r)/2)-1,d^1);
    build(p->ch[1],((l+r)/2)+1,r,d^1);
    p->pushup();  
    
}
void query_max(KD_Tree *p,Point cmp){
    if(p==NULL) return;
    maximum=max(dis(p->ponit,cmp),maximum);
    int Dis[2]={p->ch[0]==NULL?0:p->ch[0]->calc_max(cmp),p->ch[1]==NULL?0:p->ch[1]->calc_max(cmp)};
    int first=Dis[0]>Dis[1]?0:1;
    if(Dis[first]>maximum) query_max(p->ch[first],cmp);
    if(Dis[first^1]>maximum) query_max(p->ch[first^1],cmp);
}
void query_min(KD_Tree *p,Point cmp){
    if(p==NULL) return;
    if(dis(p->ponit,cmp)) minimum=min(dis(p->ponit,cmp),minimum);
    int Dis[2]={p->ch[0]==NULL?0x7f7f7f7f:p->ch[0]->calc_min(cmp),p->ch[1]==NULL?0x7f7f7f7f:p->ch[1]->calc_min(cmp)};
    int first=Dis[0]<Dis[1]?0:1;
    if(Dis[first]<minimum) query_min(p->ch[first],cmp);
    if(Dis[first^1]<minimum) query_min(p->ch[first^1],cmp); 
}
int query_max(Point cmp){
    maximum=0,query_max(root,cmp);
    return maximum;
}
int query_min(Point cmp){
    minimum=0x7fffffff,query_min(root,cmp);
    return minimum;
}
int main(){
    scanf("%d",&n);
    ans=0x7f7f7f7f;
    for(int i=1;i<=n;i++) scanf("%d%d",&sour[i].x[0],&sour[i].x[1]);
    build(root,1,n,0);
    for(int i=1;i<=n;i++){
        ans=min(ans,query_max(sour[i])-query_min(sour[i]));
    }
    printf("%d\n",ans);
}
Decadent to me ah

 Chocolate Kingdom

 Each point record with its sub-tree rooted in the x, y minimum and maximum subtree h and, why should this happen? Because if there are only records the minimum value can not be negative judgment, only records maximum and minimum time out

    And not only records the maximum and minimum values ​​can be hundred percent sure whether to go down, and be able to determine all the chocolate tree subtree is not all can accept, if all can accept it, they do not go down, directly $ ans + = a * \ sumx + b * \ sumy $, and then return to

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long

int n,m,sz,now;
ll sum,a,b,c;

struct Cho{
    ll x[2],h;
}chok[51000];
int comp(Cho a,Cho b){
    return a.x[now]<b.x[now];
}
struct KD_Tree{
    KD_Tree *ch[2];
    Cho qiao;
    ll minn[2],maxn[2],hsum;
    void redef(Cho a){
        Qiao = a, a [ 0 ] = maxn [ 0 ] = ax [ 0 ], a [ 1 ] = maxn [ 1 ] = ax [ 1 ], ch [ 0 ] = ch [ 1 ] = NULL; 
        hsum = ah; 
    } 
    Void update (KD_Tree * a) { 
        a [ 0 ] = min (a [ 0 ], a-> a [ 0 ]); 
        by [ 1 ] = min (from [ 1 ], a-> from [ 1 ]); 
        maxn [ 0 ] = max (maxn [ 0 ], a-> maxn [ 0 ]);
        maxn[1]=max(maxn[1],a->maxn[1]);
        hsum+=a->hsum;
    }
    void pushup(){
        if(ch[0]) update(ch[0]);
        if(ch[1]) update(ch[1]);
    }
    ll calc_C(){
        return min(a*minn[0],a*maxn[0])+min(b*minn[1],b*maxn[1]);
    }
    
}*root,tr[51000];
void build(KD_Tree *&p,int l,int r,int d){
    if(l>r) return;
    p=tr+(sz++),now=d;
    nth_element(chok+l,chok+((l+r)/2),chok+(r+1),comp);
    p->redef(chok[(l+r)/2]);
    build(p->ch[0],l,(l+r)/2-1,d^1);
    build(p->ch[1],(l+r)/2+1,r,d^1);
    p->pushup();
}
int judge(KD_Tree *p){
    ll x=a>0?p->maxn[0]:p->minn[0],
       y=b>0?p->maxn[1]:p->minn[1];
    return a*x+b*y<c;
}
void query_sum(KD_Tree *p){
    if(p==NULL) return;
    if(judge(p)){
        sum+=p->hsum;
        return;
    }
    if((p->qiao.x[0]*a+p->qiao.x[1]*b)<c) sum+=p->qiao.h;
    ll Dis[2]={p->ch[0]==NULL?0:p->ch[0]->calc_C(),p->ch[1]==NULL?0:p->ch[1]->calc_C()};
    if(Dis[0]<c&&p->ch[0]) query_sum(p->ch[0]);
    if(Dis[1]<c&&p->ch[1]) query_sum(p->ch[1]);
}
void query_sum(){
    sum=0;
    query_sum(root);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%lld%lld%lld",&chok[i].x[0],&chok[i].x[1],&chok[i].h);
    build(root,1,n,0);
    while(m--){
        scanf("%lld%lld%lld",&a,&b,&c);
        query_sum();
        printf("%lld\n",sum);
    }
}
View Code

To be continued ~

Guess you like

Origin www.cnblogs.com/heoitys/p/11297810.html