正题
题目链接:https://www.luogu.com.cn/problem/P4169
题目大意
nnn个点,然后每次操作
- 加一个新的点
- 询问一个点更近的点
解题思路
定义tit_iti表示第几个操作,开始就有的点tit_iti为000
假设最近的点在左上角,那么有要求ti<tj,xi<xj,yi<yjt_i<t_j,x_i<x_j,y_i<y_jti<tj,xi<xj,yi<yj构成了一个三维偏序。
对于一个点对(i,j)(i,j)(i,j),权值是xi−xj+yi−yj⇒xi+yi−(xj+yj)x_i-x_j+y_i-y_j\Rightarrow x_i+y_i-(x_j+y_j)xi−xj+yi−yj⇒xi+yi−(xj+yj)。用树状数组维护xi+yix_i+y_ixi+yi的前缀maxmaxmax即可
然后旋转一下坐标就行了,时间复杂度O(nlog2n)O(n\log^2n)O(nlog2n)
codecodecode
/*#pragma GCC optimize(2)
%:pragma GCC optimize(3)
%:pragma GCC optimize("Ofast")*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define lowbit(x) (x&-x)
using namespace std;
const int N=6e5+10,K=1e6+1;
struct node{int x,y,id,t;
}a[N],b[N];
int n,m,tot,cnt,t[K+10],ans[N];
int read() {int x=0,f=1; char c=getchar();while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();return x*f;
}
void print(int x){if (x>9) print(x/10); putchar(x%10+48); return;
}
void Change(int x,int val){x++;while(x<=K){t[x]=max(t[x],val);x+=lowbit(x);}return;
}
void Clear(int x){x++;while(x<=K){t[x]=-1e7;x+=lowbit(x);} return;
}
int Ask(int x){ int ans=-1e7;x++;while(x){ans=max(ans,t[x]);x-=lowbit(x);}return ans;
}
bool cmp(node x,node y)
{return x.t<y.t;}
void merge(int l,int mid,int r){int L=l,R=mid+1,z=l;while(z<=r){if((a[L].x<=a[R].x||R>r)&&L<=mid)b[z++]=a[L++];else if(a[L].x>a[R].x||L>mid)b[z++]=a[R++];}for(int i=l;i<=r;i++)a[i]=b[i];return;
}
void cdq(int l,int r){if(l==r)return;int mid=(l+r)>>1;cdq(l,mid);cdq(mid+1,r);int z=l;for(int i=mid+1;i<=r;i++){while(z<=mid&&a[z].x<=a[i].x){if(a[z].id==0)Change(a[z].y,a[z].x+a[z].y);z++;}if(a[i].id!=0)ans[a[i].id]=min(ans[a[i].id],a[i].x+a[i].y-Ask(a[i].y));}for(int i=l;i<z;i++)Clear(a[i].y);merge(l,mid,r);return;
}
int main()
{n=read();m=read(); for(int i=1;i<=n;i++){a[i].x=read()+1;a[i].y=read();a[i].t=i;}for(int i=1;i<=m;i++){int op=read();a[++n].t=n;a[n].x=read()+1;a[n].y=read(); if(op==2)a[n].id=++cnt;}sort(a+1,a+1+n,cmp);memset(t,0xcf,sizeof(t));memset(ans,0x3f,sizeof(ans));cdq(1,n);for(int i=1;i<=n;i++)a[i].x=K-a[i].x;sort(a+1,a+1+n,cmp);cdq(1,n);for(int i=1;i<=n;i++)a[i].y=K-a[i].y;sort(a+1,a+1+n,cmp);cdq(1,n);for(int i=1;i<=n;i++)a[i].x=K-a[i].x;sort(a+1,a+1+n,cmp);cdq(1,n);for(int i=1;i<=cnt;i++)print(ans[i]),putchar('\n');
}