kd-tree
kd-tree不重构居然能过?23333。。。
就当屯一个模板吧。
#include<cstdio>
#include<algorithm>
#define N 1000005
#define cmin(u,v) (u)>(v)?(u)=(v):0
#define cmax(u,v) (u)<(v)?(u)=(v):0
using namespace std;
namespace ziqian
{
int in()
{
int r = 0; char c = getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')r=r*10+c-'0',c=getchar();
return r;
}
const int INF = 1<<30;
int D, root, ans, x, y;
struct Point{int d[2];}p[N];
struct KDT{int d[2], x[2], y[2], ch[2];}t[N];
bool operator < (Point a, Point b) {return a.d[D] < b.d[D] || (a.d[D] == b.d[D] && a.d[D^1] < b.d[D^1]);}
void make_KDT(int f, int x)
{
cmin(t[f].x[0], t[x].x[0]); cmax(t[f].x[1], t[x].x[1]);
cmin(t[f].y[0], t[x].y[0]); cmax(t[f].y[1], t[x].y[1]);
}
int build_KDT(int l, int r, int d)
{
D = d; int mid = (l+r)>>1;
nth_element(p+l,p+mid,p+1+r);
t[mid].d[0] = t[mid].x[0] = t[mid].x[1] = p[mid].d[0];
t[mid].d[1] = t[mid].y[0] = t[mid].y[1] = p[mid].d[1];
if(l<mid) t[mid].ch[0] = build_KDT(l,mid-1,d^1), make_KDT(mid,t[mid].ch[0]);else t[mid].ch[0] = 0;
if(mid<r) t[mid].ch[1] = build_KDT(mid+1,r,d^1), make_KDT(mid,t[mid].ch[1]);else t[mid].ch[1] = 0;
return mid;
}
void insert_KDT(int pos)
{
D = 0;
for(int o = root; o; D ^= 1)
{
make_KDT(o, pos);
int &nxt = t[o].ch[ t[o].d[D] <= t[pos].d[D] ];
if(!nxt){nxt = pos; return;} else o = nxt;
}
}
int abs(int x){return x<0?-x:x;}
int get_dis(int p){return max(t[p].x[0]-x,0)+max(x-t[p].x[1],0)+max(t[p].y[0]-y,0)+max(y-t[p].y[1],0);}
void query_KDT(int o)
{
int tmp = abs(t[o].d[0]-x)+abs(t[o].d[1]-y), d[2] = {INF, INF}; cmin(ans, tmp);
if(t[o].ch[0]) d[0] = get_dis(t[o].ch[0]); if(t[o].ch[1]) d[1] = get_dis(t[o].ch[1]);
int nxt = d[1] <= d[0];
if(d[nxt] < ans) query_KDT(t[o].ch[nxt]);
if(d[nxt^1] < ans)query_KDT(t[o].ch[nxt^1]);
}
void main()
{
int n=in(), m=in();
for(int i = 1; i <= n; i++)p[i].d[0] = in(), p[i].d[1]=in();
root = build_KDT(1,n,0);
for(int i = 1; i <= m; i++)
{
int opt = in();
if(opt == 1)
{
++n;
t[n].d[0] = t[n].x[0] = t[n].x[1] = in();
t[n].d[1] = t[n].y[0] = t[n].y[1] = in();
insert_KDT(n);
}
else
{
x = in(); y = in(); ans = INF; query_KDT(root);
printf("%d\n",ans);
}
}
}
}
int main()
{
ziqian::main();
}