1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
const int N=5e5+10; namespace MAIN{ int n; int D; struct P{ int x[2],val; inline bool operator < (const P &b) const { return x[D]<b.x[D]; } }a[N]; inline P init(const res &X,const res &Y,const res &v){ RG P b; b.x[0]=X,b.x[1]=Y,b.val=v; return b; } struct KDT{ #define alph (0.75) struct KD{ int son[2],mx[2],mn[2],sz; LL sum; P point; inline void init(const RG P &b){ point=b,son[0]=son[1]=0,mx[0]=mn[0]=b.x[0],mx[1]=mn[1]=b.x[1],sum=b.val,sz=1; } }tr[N]; int tot; int st[N],top; inline int newnode(){ return top?st[top--]:++tot; } inline void pushup(res rt){ res ls=tr[rt].son[0],rs=tr[rt].son[1]; tr[rt].sum=tr[ls].sum+tr[rs].sum+tr[rt].point.val; tr[rt].sz=tr[ls].sz+tr[rs].sz+1; for(res i=0;i<=1;i++){ tr[rt].mn[i]=min({tr[ls].mn[i],tr[rs].mn[i],tr[rt].point.x[i]}); tr[rt].mx[i]=max({tr[ls].mx[i],tr[rs].mx[i],tr[rt].point.x[i]}); } } inline void slap(res rt,res num){ if(tr[rt].son[0])slap(tr[rt].son[0],num); a[num+tr[tr[rt].son[0]].sz+1]=tr[rt].point,st[++top]=rt; if(tr[rt].son[1])slap(tr[rt].son[1],num+tr[tr[rt].son[0]].sz+1); } int build(res l,res r,res d){ if(l>r)return 0; res rt=newnode(),mid=(l+r)>>1; D=d,nth_element(a+l,a+mid,a+r+1),tr[rt].point=a[mid]; tr[rt].son[0]=build(l,mid-1,d^1),tr[rt].son[1]=build(mid+1,r,d^1); pushup(rt); return rt; } inline void check(res &rt,res d){ if(alph*tr[rt].sz<tr[tr[rt].son[0]].sz||alph*tr[rt].sz<tr[tr[rt].son[1]].sz)slap(rt,0),rt=build(1,tr[rt].sz,d); } void insert(res &rt,const RG P &p,res d){ if(!rt){ rt=newnode(),tr[rt].init(p); return; } if(tr[rt].point.x[d]<p.x[d])insert(tr[rt].son[1],p,d^1); else insert(tr[rt].son[0],p,d^1); pushup(rt),check(rt,d); } int Rt; #define XW const res &x1,const res &y1,const res &r #define XWW x1,y1,r #define XWWW tr[rt].point.x[0],tr[rt].point.x[1] #define XWWWW const res &X1,const res &Y1 inline bool bh(const res &rt,XW){ res cnt=0; cnt+=(1ll*(x1-tr[rt].mn[0])*(x1-tr[rt].mn[0])+1ll*(y1-tr[rt].mn[1])*(y1-tr[rt].mn[1])<=1ll*r*r); cnt+=(1ll*(x1-tr[rt].mn[0])*(x1-tr[rt].mn[0])+1ll*(y1-tr[rt].mx[1])*(y1-tr[rt].mx[1])<=1ll*r*r); cnt+=(1ll*(x1-tr[rt].mx[0])*(x1-tr[rt].mx[0])+1ll*(y1-tr[rt].mn[1])*(y1-tr[rt].mn[1])<=1ll*r*r); cnt+=(1ll*(x1-tr[rt].mx[0])*(x1-tr[rt].mx[0])+1ll*(y1-tr[rt].mx[1])*(y1-tr[rt].mx[1])<=1ll*r*r); return cnt==4; } inline bool bh(XWWWW,XW){ return 1ll*(x1-X1)*(x1-X1)+1ll*(y1-Y1)*(y1-Y1)<=1ll*r*r; } inline bool xj(res rt,XW){ res x,y; if(tr[rt].mn[0]<=x1&&x1<=tr[rt].mx[0])x=x1; else if(tr[rt].mn[0]>x1)x=tr[rt].mn[0]; else x=tr[rt].mx[0]; if(tr[rt].mn[1]<=y1&&y1<=tr[rt].mx[1])y=y1; else if(tr[rt].mn[1]>y1)y=tr[rt].mn[1]; else y=tr[rt].mx[1]; return 1ll*(x1-x)*(x1-x)+1ll*(y1-y)*(y1-y)>1ll*r*r; } LL query(res rt,XW){ if(!rt||xj(rt,XWW))return 0; if(bh(rt,XWW))return tr[rt].sum; res ret=0; if(bh(XWWW,XWW))ret+=tr[rt].point.val; return ret+query(tr[rt].son[0],XWW)+query(tr[rt].son[1],XWW); } }A; inline void MAIN(){ A.tr[0].mn[0]=A.tr[0].mn[1]=inf,A.tr[0].mx[0]=A.tr[0].mx[1]=-inf; res T=read(); while(T--){ n=read(),A.tot=A.top=A.Rt=0; for(res i=1;i<=n;i++){ res x=read(),y=read(),v=read(),r=read(); A.insert(A.Rt,init(x,y,v),0),printf("%lld\n",A.query(A.Rt,x,y,r)); } } } }
|