如果只考虑左下角的玩偶这道题就是三维偏序了。那么只要翻转四次,四次 cdq 就好了。
#include <cstdio>
#include <cstring>
#include <algorithm>
inline unsigned read(void){
unsigned res = 0; char ch = std::getchar();
while(ch < '0' || ch > '9')
ch = std::getchar();
while(ch >= '0' && ch <= '9')
res = res * 10 + ch - 48, ch = std::getchar();
return res;
}
const int MAXN = 3e5 + 19, MAXV = 1e6 + 19;
struct Node{
int t, x, y, dist;
int q;
bool operator<(const Node& b)const{
return t != b.t ? t < b.t : (x != b.x ? x < b.x : y < b.y);
}
}node[MAXN << 1], tmp[MAXN << 1];
int n, m, ans[MAXN];
class Tarr{
private:
int tr[MAXV + 10], n;
public:
void clear(void){
std::memset(tr, 0, sizeof tr);
}
void clear(int x){
for(; x <= n; x += x & -x)
if(tr[x])
tr[x] = 0;
else
break;
}
void set(int size){
n = size;
}
void update(int x, int k){
for(; x <= n; x += x & -x)
tr[x] = std::max(tr[x], k);
}
int query(int x){
int res = 0;
for(; x; x -= x & - x)
res = std::max(res, tr[x]);
return res ? res : -0x3f3f3f3f;
}
}myTree;
void cdq(int l, int r){
if(l == r)
return;
int mid = (l + r) >> 1;
cdq(l, mid), cdq(mid + 1, r);
int p = l, q = mid + 1, cnt = l;
while(p <= mid && q <= r)
if(node[p].x <= node[q].x){
if(!node[p].q)
myTree.update(node[p].y, node[p].x + node[p].y);
tmp[cnt++] = node[p++];
}
else{
if(node[q].q)
node[q].dist = std::min(node[q].dist, node[q].x + node[q].y - myTree.query(node[q].y));
tmp[cnt++] = node[q++];
}
while(p <= mid)
tmp[cnt++] = node[p++];
while(q <= r){
if(node[q].q)
node[q].dist = std::min(node[q].dist, node[q].x + node[q].y - myTree.query(node[q].y));
tmp[cnt++] = node[q++];
}
for(int i = l; i <= mid; ++i)
if(!node[i].q)
myTree.clear(node[i].y);
for(int i = l; i <= r; ++i)
node[i] = tmp[i];
}
int q;
int main(){
#ifndef ONLINE_JUDGE
std::freopen("P4169_11.in", "r", stdin);
std::freopen("P4169_11.out", "w", stdout);
#endif
n = read(), m = read();
for(int i = 1; i <= n; ++i)
node[i].t = 1, node[i].x = read(), node[i].y = read() + 1, node[i].dist = 0;
for(int i = n + 1; i <= n + m; ++i){
if(read() == 2)
node[i].q = ++q;
node[i].t = i - n + 1, node[i].x = read(), node[i].y = read() + 1, node[i].dist = 0x7fffffff;
}
myTree.set(MAXV + 3);
std::sort(node + 1, node + 1 + n + m);
cdq(1, n + m);
for(int i = 1; i <= n + m; ++i)
node[i].x = MAXV - node[i].x;
std::sort(node + 1, node + 1 + n + m);
cdq(1, n + m);
for(int i = 1; i <= n + m; ++i)
node[i].x = MAXV - node[i].x, node[i].y = MAXV - node[i].y;
std::sort(node + 1, node + 1 + n + m);
cdq(1, n + m);
for(int i = 1; i <= n + m; ++i)
node[i].x = MAXV - node[i].x;
std::sort(node + 1, node + 1 + n + m);
cdq(1, n + m);
for(int i = 1; i <= n + m; ++i)
if(node[i].q)
ans[node[i].q] = node[i].dist;
for(int i = 1; i <= q; ++i)
std::printf("%d\n", ans[i]);
return 0;
}