# BZOJ2648/2716:SJY摆棋子/[Violet]天使玩偶(K-D Tree)

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

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\n",ans);
150         }
151     }
152 }
posted @ 2018-07-12 19:58  Refun  阅读(193)  评论(0编辑  收藏  举报