Topic: Dynamic Point Addition. Ask Manhattan's nearest point at a given point
N,M≤3e5,x,y≤1e6N,M \leq 3e5,x,y \leq 1e6N,M≤3e5,x,y≤1e6
After (kan) Le (ti) analysis (jie), this is a cdqcdqcdq Division
Consider the influence of the modification of the left half of the current interval on the query on the right half
Let one on the left be modified to (x1, y1) (x1, y1) (x1, y1) and one on the right be (x2, y2) (x2, y2) (x2, y2)
Considering the cases of X1 < x2,y1 < Y2 x_1 Leq x_2, y1 Leq y_2x1 < x2,y1 < y2, the answer is x2+y2 x1 y1x_2 + y2-x_1-y_1x_2 + Y2 X1 y1
Because coordinates are linear, you need to sort out one dimension.
Sort left and right in xxx coordinates
This allows you to remove the xxx restriction with double pointers
The y YYY coordinate opens a tree array and records no more than the largest x+yx+yx+y in yyy's modifications
Then it's easy to calculate the answer.
The other three cases are similar.
In order to achieve convenience, the coordinate system is rotated directly, i.e. infinfinf subtraction.
Tree arrays already have logloglog logs, and we have no fear, so we can sort them directly.
Complexity O(NlogN2)O(Nlog_N^2)O(NlogN2)
#include <iostream> #include <cstdio> #include <cstring> #include <cctype> #include <algorithm> #define MAXN 600005 #define MAXM 2000005 #define MAX 1000000 using namespace std; inline int read() { int ans=0; char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar(); return ans; } int n,m,siz; struct BIT { int s[MAXM]; inline int lowbit(const int& x){return x&-x;} inline void modify(int x,const int& v){for (;x<=(MAX<<1);s[x]=max(s[x],v),x+=lowbit(x));} inline int query(int x){int ans=-0x3f3f3f3f;for (;x;ans=max(ans,s[x]),x-=lowbit(x));return ans;} inline void clear(int x){for (;x<=(MAX<<1);s[x]=-0x3f3f3f3f,x+=lowbit(x));} }bit; int ans[MAXN]; struct query{int type,x,y,pos;}q[MAXN]; inline bool operator <(const query& a,const query& b){if (a.x==b.x) return a.y<b.y;return a.x<b.x;} void calc(int l,int r) { int now=l-1,mid=(l+r)>>1; for (int i=mid+1;i<=r;i++) { if (q[i].type==1) continue; while (now<mid&&q[now+1].x<=q[i].x) { ++now; if (q[now].type==1) bit.modify(q[now].y,q[now].x+q[now].y); } ans[q[i].pos]=min(ans[q[i].pos],q[i].x+q[i].y-bit.query(q[i].y)); } for (int i=l;i<=mid;i++) bit.clear(q[i].y); } void cdq(int l,int r) { if (l==r) return; int mid=(l+r)>>1; cdq(l,mid); cdq(mid+1,r); calc(l,r); for (int i=l;i<=r;i++) q[i].x=MAX-q[i].x; sort(q+l,q+mid+1),sort(q+mid+1,q+r+1); calc(l,r); for (int i=l;i<=r;i++) q[i].y=MAX-q[i].y; sort(q+l,q+mid+1),sort(q+mid+1,q+r+1); calc(l,r); for (int i=l;i<=r;i++) q[i].x=MAX-q[i].x; sort(q+l,q+mid+1),sort(q+mid+1,q+r+1); calc(l,r); for (int i=l;i<=r;i++) q[i].y=MAX-q[i].y; sort(q+l,q+r+1); } int main() { n=read(),m=read(); for (int i=1;i<=n;i++) q[i].type=1,q[i].x=read()+1,q[i].y=read()+1; for (int i=1;i<=m;i++) q[n+i].type=read(),q[n+i].x=read()+1,q[n+i].y=read()+1,q[n+i].pos=i; memset(ans,0x3f,sizeof(ans)); for (int i=0;i<MAXM;i++) bit.s[i]=-0x3f3f3f3f; cdq(1,n+m); for (int i=1;i<=m;i++) if (ans[i]<0x3f3f3f3f) printf("%d\n",ans[i]); return 0; }