存模板
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define SF scanf
#define PF printf
#define mp make_pair
#define sqr(x) ((x)*(x))
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
using namespace std;
typedef long long LL;
const int MAXN = 500000;
const int INF = 0x3f3f3f3f;
struct Node {
int d[2], mn[2], mx[2];
int l, r;
int operator [] (int x) const { return d[x]; }
int & operator [] (int x) { return d[x]; }
Node (int x = 0, int y = 0) {
l = r = 0; d[0] = x; d[1] = y;
}
} A[MAXN+10];
int direction;
bool operator < (const Node &a, const Node &b) {
return a[direction] < b[direction];
}
inline LL dis(const Node &a, const Node &b) {
return abs(a[0]-b[0])+abs(a[1]-b[1]);
}
struct kd_Tree {
int ans;
int ncnt, root;
Node t[MAXN*2+10], T;
inline void up(int x) {
Node &u = t[x];
Node l = t[u.l], r = t[u.r];
for(int i = 0; i < 2; i++) {
if(u.l) u.mn[i] = min(u.mn[i], l.mn[i]), u.mx[i] = max(u.mx[i], l.mx[i]);
if(u.r) u.mn[i] = min(u.mn[i], r.mn[i]), u.mx[i] = max(u.mx[i], r.mx[i]);
}
}
int build(int l, int r, int dir, Node *p) {
direction = dir;
int mid = (l+r) >> 1;
nth_element(p+l, p+mid, p+r+1);
t[mid] = p[mid];
for(int i = 0; i < 2; i++)
t[mid].mn[i] = t[mid].mx[i] = t[mid][i];
if(l < mid) t[mid].l = build(l, mid-1, dir^1, p);
if(r > mid) t[mid].r = build(mid+1, r, dir^1, p);
up(mid);
return mid;
}
inline void ins(int k, int dir) {
Node &u = t[k];
if(T[dir] >= u[dir]) {
if(u.r) ins(u.r, dir^1);
else {
u.r = ++ncnt; t[ncnt] = T;
for(int i = 0; i < 2; i++)
t[ncnt].mn[i] = t[ncnt].mx[i] = t[ncnt][i];
}
}
else {
if(u.l) ins(u.l, dir^1);
else {
u.l = ++ncnt; t[ncnt] = T;
for(int i = 0; i < 2; i++)
t[ncnt].mn[i] = t[ncnt].mx[i] = t[ncnt][i];
}
}
up(k);
}
inline LL get_dis(int k, const Node &p) {
LL ret = 0;
for(int i = 0; i < 2; i++) ret += max(0, p[i] - t[k].mx[i]);
for(int i = 0; i < 2; i++) ret += max(0, t[k].mn[i] - p[i]);
return ret;
}
inline void query(int x, int dir) {
Node &u = t[x];
int d = dis(u, T);
int dl = INF, dr = INF;
ans = min(ans, d);
if(u.l) dl = get_dis(u.l, T);
if(u.r) dr = get_dis(u.r, T);
if(dl < dr) {
if(dl < ans) query(u.l, dir^1);
if(dr < ans) query(u.r, dir^1);
}
else {
if(dr < ans) query(u.r, dir^1);
if(dl < ans) query(u.l, dir^1);
}
}
inline void ins(const Node &p) {
T = p; ins(root, 0);
}
inline int query(const Node &p) {
ans = INF; T = p; query(root, 0);
return ans;
}
} kd;
int n, m, x;
int main() {
SF("%d%d", &n, &m);
for(int i = 1; i <= n; i++) SF("%d%d", &A[i][0], &A[i][1]);
kd.ncnt = n;
kd.root = kd.build(1, n, 0, A);
for(int i = 1; i <= m; i++) {
int op, x, y;
SF("%d%d%d", &op, &x, &y);
if(op == 1) kd.ins(Node(x, y));
else PF("%d\n", kd.query(Node(x, y)));
}
}