Yoi #388.紅點藍點
阿新 • • 發佈:2020-11-30
題面
分析
分成四部分,每部分用線段樹維護,由於有刪除操作,所以每個葉子節點用\(multiset\)維護
時間複雜度均攤\(O(nlgn)\)
注意:點權可能是負數,所以$c[0]=-INF
#include<bits/stdc++.h> const int INF=1e9; using namespace std; const int N=1e5+5; int n,m,d,ans[N],num; struct A{int a,b,id; }a[N],b[N]; namespace sss { bool cmp(A i,A j) { return i.b<j.b; } const int N=3e6+6; bool fl; struct B{ int c[N],ls[N],rs[N],cnt,id,num[N]; multiset<int>s[100000]; void ins(int &p,int l,int r,int x,int k) { if(!p) { p=++cnt; c[p]=-INF; } if(l==r) { c[p]=max(c[p],k); if(!num[p]) num[p]=++id; s[num[p]].insert(k); return; } int mid=l+r>>1; if(x<=mid) ins(ls[p],l,mid,x,k); else ins (rs[p],mid+1,r,x,k); c[p]=max(c[ls[p]],c[rs[p]]); } void del(int p,int l,int r,int x,int k) { if(l==r) { auto x=s[num[p]].lower_bound(k); s[num[p]].erase(x); if(s[num[p]].begin()==s[num[p]].end()) c[p]=-INF; else { x=s[num[p]].end(); x--; c[p]=*x; } return; } int mid=l+r>>1; if(x<=mid) del(ls[p],l,mid,x,k); else del(rs[p],mid+1,r,x,k); c[p]=max(c[ls[p]],c[rs[p]]); } int ask(int p,int l,int r,int x,int y) { if(!p) return -INF; if(l==x&&r==y) return c[p]; int mid=l+r>>1; if(y<=mid) return ask(ls[p],l,mid,x,y); if(x>mid) return ask(rs[p],mid+1,r,x,y); return max(ask(ls[p],l,mid,x,mid),ask(rs[p],mid+1,r,mid+1,y)); } /* bool is_clear(int p,int l,int r) { if(!p) return 1; if(l==r) { if(s[num[p]].begin()==s[num[p]].end()) return 1; return 0; } int mid=l+r>>1; return is_clear(ls[p],l,mid)&is_clear(rs[p],mid+1,r); }*/ }c1,c2; void main() { int rt=1; c1.cnt=1,c2.cnt=1; c1.c[0]=-INF,c2.c[0]=-INF; sort(a+1,a+n+1,cmp); sort(b+1,b+n+1,cmp); int l=1,r=0; for(int i=1;i<=n;i++) ans[i]=INF; for(int i=1;i<=n;i++) { while(r<=n&&a[i].b>=b[r+1].b) { r++; c1.ins(rt,0,m,b[r].a,b[r].b+b[r].a); c2.ins(rt,0,m,b[r].a,b[r].b-b[r].a); } while(l<=r&&a[i].b-b[l].b>d) { c1.del(rt,0,m,b[l].a,b[l].b+b[l].a); c2.del(rt,0,m,b[l].a,b[l].b-b[l].a); l++; } if(l<=r) { ans[a[i].id]=min(ans[a[i].id],-c1.ask(rt,0,m,0,a[i].a)+a[i].a+a[i].b); ans[a[i].id]=min(ans[a[i].id],-c2.ask(rt,0,m,a[i].a,m)-a[i].a+a[i].b); } } for(int i=l;i<=r;i++) { c1.del(rt,0,m,b[i].a,b[i].b+b[i].a); c2.del(rt,0,m,b[i].a,b[i].b-b[i].a); } l=n,r=n+1; fl=0; for(int i=n;i;i--) { while(r>1&&a[i].b<b[r-1].b) { r--; c1.ins(rt,0,m,b[r].a,-b[r].b+b[r].a); c2.ins(rt,0,m,b[r].a,-b[r].b-b[r].a); } while(l>=r&&b[l].b-a[i].b>d) { c1.del(rt,0,m,b[l].a,-b[l].b+b[l].a); c2.del(rt,0,m,b[l].a,-b[l].b-b[l].a); l--; } if(l>=r) { ans[a[i].id]=min(ans[a[i].id],-c1.ask(rt,0,m,0,a[i].a)+a[i].a-a[i].b); ans[a[i].id]=min(ans[a[i].id],-c2.ask(rt,0,m,a[i].a,m)-a[i].a-a[i].b); } } for(int i=1;i<=n;i++) { printf("%d\n",ans[i]==INF?0:ans[i]); } } } int main() { freopen("portal.in","r",stdin); freopen("portal.out","w",stdout); scanf("%d%d",&n,&d); for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].a,&a[i].b); a[i].id=i; } for(int i=1;i<=n;i++) { scanf("%d%d",&b[i].a,&b[i].b); m=max(m,b[i].a); } sss::main(); return 0; }