zoukankan      html  css  js  c++  java
  • BZOJ2648/2716:SJY摆棋子/[Violet]天使玩偶(K-D Tree)

    Description

    这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。

    Input

    第一行两个数 N M
    以后M行,每行3个数 t x y
    如果t=1 那么放下一个黑色棋子
    如果t=2 那么放下一个白色棋子

    Output

    对于每个T=2 输出一个最小距离

    Sample Input

    2 3
    1 1
    2 3
    2 1 2
    1 3 3
    2 4 2

    Sample Output

    1
    2

    Solution

    K-D Tree模板题,注意不替罪羊重构的话会TLE

    Code

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<algorithm>
      6 #define N (1000000+1000)
      7 #define INF 0x7fffffff
      8 using namespace std;
      9 
     10 int n,m,D,ans,opt,x,y,Root;
     11 double alpha=0.75;
     12 
     13 struct Node
     14 {
     15     int d[2],Max[2],Min[2],lson,rson,size;
     16     bool operator < (const Node &a) const {return d[D]<a.d[D];}
     17     Node (int x=0,int y=0)
     18     {
     19         lson=rson=0; d[0]=x; d[1]=y;;
     20         Max[0]=Min[0]=d[0];
     21         Max[1]=Min[1]=d[1];
     22     }
     23 }p[N],T;
     24 
     25 int stack[N],cnt,top;
     26 int NewNode()
     27 {
     28     if (top) return stack[top--];
     29     return ++cnt;
     30 }
     31 
     32 struct KDT
     33 {
     34     Node Tree[N];
     35     
     36     void Update(int now)
     37     {
     38         int ls=Tree[now].lson,rs=Tree[now].rson;
     39         for (int i=0; i<=1; ++i)
     40         {
     41             Tree[now].Max[i]=Tree[now].Min[i]=Tree[now].d[i];
     42             if (ls)
     43             {
     44                 Tree[now].Max[i]=max(Tree[now].Max[i],Tree[ls].Max[i]);
     45                 Tree[now].Min[i]=min(Tree[now].Min[i],Tree[ls].Min[i]);
     46             }
     47             if (rs)
     48             {
     49                 Tree[now].Max[i]=max(Tree[now].Max[i],Tree[rs].Max[i]);
     50                 Tree[now].Min[i]=min(Tree[now].Min[i],Tree[rs].Min[i]);
     51             }
     52         }
     53         Tree[now].size=Tree[ls].size+Tree[rs].size+1;
     54     }
     55     int Build(int opt,int l,int r)
     56     {
     57         if (l>r) return 0;
     58         int mid=(l+r)>>1,now=NewNode();
     59         D=opt; nth_element(p+l,p+mid,p+r+1);
     60         Tree[now]=p[mid]; Tree[now].size=1;
     61         Tree[now].lson=Build(opt^1,l,mid-1);
     62         Tree[now].rson=Build(opt^1,mid+1,r);
     63         Update(now);
     64         return now;
     65     }
     66     int Get_min(int now)
     67     {
     68         int ans=0;
     69         for (int i=0; i<=1; ++i)
     70         {
     71             ans+=max(0,T.d[i]-Tree[now].Max[i]);
     72             ans+=max(0,Tree[now].Min[i]-T.d[i]);
     73         }
     74         return ans;
     75     }
     76     void Query(int now)
     77     {
     78         ans=min(ans,abs(T.d[0]-Tree[now].d[0])+abs(T.d[1]-Tree[now].d[1]));
     79         int ls=Tree[now].lson,rs=Tree[now].rson,lans=INF,rans=INF;
     80         if (ls) lans=Get_min(ls);
     81         if (rs) rans=Get_min(rs);
     82         if (lans<rans)
     83         {
     84             if (lans<ans) Query(ls);
     85             if (rans<ans) Query(rs);
     86         }
     87         else
     88         {
     89             if (rans<ans) Query(rs);
     90             if (lans<ans) Query(ls);
     91         }
     92     }
     93     void Dfs(int now,int sz)
     94     {
     95         int ls=Tree[now].lson,rs=Tree[now].rson;
     96         if (ls) Dfs(ls,sz);
     97         p[sz+Tree[ls].size]=Tree[now];
     98         stack[++top]=now;
     99         if (rs) Dfs(rs,sz+Tree[ls].size+1);
    100     }
    101     void Check(int &now,int opt)
    102     {
    103         int ls=Tree[now].lson, rs=Tree[now].rson;
    104         if (Tree[ls].size>alpha*Tree[now].size || Tree[rs].size>alpha*Tree[now].size)
    105         {
    106             Dfs(now,1);
    107             now=Build(opt,1,Tree[now].size);
    108         }
    109     }
    110     void Insert(int &now,int x,int opt)
    111     {
    112         if (Tree[x].d[opt]<=Tree[now].d[opt])
    113         {
    114             if (Tree[now].lson) Insert(Tree[now].lson,x,opt^1);
    115             else Tree[now].lson=x;
    116         }
    117         else
    118         {
    119             if (Tree[now].rson) Insert(Tree[now].rson,x,opt^1);
    120             else Tree[now].rson=x;
    121         }
    122         Update(now); Check(now,opt);
    123     }
    124 }KDT;
    125 
    126 int main()
    127 {
    128     scanf("%d%d",&n,&m);
    129     for (int i=1; i<=n; ++i)
    130     {
    131         scanf("%d%d",&x,&y);
    132         p[i].d[0]=x; p[i].d[1]=y;
    133     }
    134     Root=KDT.Build(0,1,n);
    135     for (int i=1; i<=m; ++i)
    136     {
    137         scanf("%d%d%d",&opt,&x,&y);
    138         if (opt==1)
    139         {
    140             int t=NewNode();
    141             KDT.Tree[t]=Node(x,y);
    142             KDT.Tree[t].size=1;
    143             KDT.Insert(Root,t,0);
    144         }
    145         else
    146         {
    147             T.d[0]=x; T.d[1]=y; ans=INF;
    148             KDT.Query(Root);
    149             printf("%d
    ",ans);
    150         }
    151     }
    152 }
  • 相关阅读:
    排序去重
    $(...)[0].attr is not a function问题
    daterangepicker的汉化和简单使用
    wx.openSetting的调整
    css3中-moz、-ms、-webkit与盒子模型
    动态翻滚的导航条
    CSS3 transition 浏览器兼容性
    jq实现两个input输入同时不为空时,改变确认框背景颜色
    js 监听input 实现数据绑定
    关于html 修改滚动条的问题
  • 原文地址:https://www.cnblogs.com/refun/p/9301608.html
Copyright © 2011-2022 走看看