Description This is a complex world. Human society, nature, and the Milky Way beyond the earth ...
Every day sunrise and sunset, coming and coming, walking in a hurry. What is it for? Is there a rule of supremacy that governs everything? Theresa know that this problem is not overnight can be answered, only after careful, in-depth observation and thinking, it is possible to link all the broken clues, so that a glimpse of the real answer.
As a result, Theresa often think about the big and small problems that are encountered in life. Why did she not know any of the Chinese characters printed in the books published by RTHK? Why is the overnight boiled water rich in hydrogen peroxide? Why is there a period of time every year in Gmail mailbox do not go?
In order to analyze these problems more systematically and scientifically, Theresa decided to ask for your help.
To make a long story short, Theresa wants you to help her implement a data structure. The function of this data structure is to maintain a set of points in a spatial Cartesian coordinate system and to support the following three types of operations:
1. Add x y Z joins a new point with the coordinates of the point (x, Y, z).
2. Query x y z R queries the number of points inside the cube (x, Y, z)-(X+r, Y+r, Z+r).
3. Cancel revokes The most recent add operation.
where x, Y, Z, R are all integers given. In the query operation, (x, Y, z) is the coordinate of a vertex of the cube, and R is the side length of the cube. The point on the cube boundary is also inside the cube.
This problem may be too difficult, so Theresa does not force you to implement an efficient data structure. However, you must give the correct answer to each query operation.
The first line of input contains an integer n, which indicates that the initial point set has n points.
Next n rows, each row contains three integers, Xi, Yi, and Zi, which in turn represent the coordinates of each point.
The n+2 line contains an integer q, which indicates that there will be a Q operation.
Next Q line, each line represents an operation, the format as the title description. output outputs several lines, one integer per line, which in turn represents the answer for each query operation. Sample Input
2
1 2 3
1 1 3
7
ADD 0 4 3
QUERY 0 0 0 4
ADD 1 1 5
QUERY 1 1 2 3
QUERY 0 2 2 1
CANCEL
QUERY 1 1 2 3
Sample Output
3
3
1
2
Sample explanation:
The 1th query is the cube (0, 0, 0)-(4, 4, 4), internally containing points (1, 2, 3), (1, 1, 3), (0, 4, 3).
The 2nd query is the cube (1, 1, 2)-(4, 4, 5), internally containing points (1, 2, 3), (1, 1, 3), (1, 1, 5).
The 3rd query of the cube (0, 2, 2)-(1, 3, 3), contains the interior points (1, 2, 3).
The 4th query is the cube (1, 1, 2)-(4, 4, 5), the interior contains points (1, 2, 3), (1, 1, 3).
Data constraint for 10%: 1≤n, Q≤1 000.
Also 10% of the data: 0≤x, Y, z≤100,1≤r≤100.
Also 30% of the data: There are no add operations and cancel operations.
Also 20% of data: no cancel operation.
70% of data: 1≤n, Q≤50 000.
For 100% data: 1≤n + q≤100 000, 0≤x, Y, Z, r≤10^7. R is a positive integer. All cancel operations are valid operations. The coordinates of the different points may overlap.
Analysis
This question is a four-dimensional partial order problem.
We use CDQ to solve the problem of the time dimension.
X we can sort of discretization
Y with a tree-like array, Z with treap (not dare to use splay constant too large 233)
So the question is a CDQ set of tree sets
(Write lowerbound, forget to add a 1 on the upper bound)
#include <iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#defineRep (i,a,b) for (i=a;i<=b;i++)#defineLowbit (x) x&-xConst intn=100005;using namespacestd;structNode {intL,r,key,mak,dat,sum;} t[ -*N];inttcnt;structPoint {intx, Y, Z;} Stk[n];structQuery {point P; intR,t,id;} q[n],a[2*N];intqcnt;intRt[n];intSy,sq,sh,n,m,top;intAns[n],y[n];//treapvoidUpdate (intx) {t[x].sum=t[x].dat+t[t[x].l].sum+t[t[x].r].sum;}voidLeft_rotate (int&x) {ints=T[X].R; T[X].R=t[s].l;t[s].l=x; Update (x); Update (s); X=s;}voidRight_rotate (int&x) {ints=T[X].L; T[X].L=t[s].r;t[s].r=x; Update (x); Update (s); X=s;}voidInsert (int&x,intMakintdat) { if(!x) {x=++tcnt;t[x].l=t[x].r=0; t[x].mak=mak;t[x].sum=t[x].dat=dat;t[x].key=rand (); return; } if(mak<T[x].mak) {Insert (T[x].l,mak,dat); if(t[t[x].l].key>T[x].key) Right_rotate (x); } Else{Insert (t[x].r,mak,dat); if(t[t[x].r].key>T[x].key) Left_rotate (x); } Update (x);}intGet_suk (intXintMak) { if(!x)return 0; if(Mak<t[x].mak)returnGet_suk (T[x].l,mak); returnGet_suk (T[x].r,mak) +t[x].dat+t[t[x].l].sum;}//TreearrayvoidADD (intXintZintdat) { for(inti=x;i<=sy+1; i+=lowbit (i)) Insert (Rt[i],z,dat);}intGet_sum (intXintZintr) {intans=0; for(intI=x;i;i-=lowbit (i)) Ans+=get_suk (rt[i],z+r)-get_suk (rt[i],z-1); returnans;}voidInit () {inti; Chars[ -]; scanf ("%d",&N); Rep (I,1, N) {sq++; scanf ("%d%d%d",&q[sq].p.x,&q[sq].p.y,&q[sq].p.z); Q[sq].id=sq;q[sq].t=1; } scanf ("%d",&m); Rep (I,1, M) {scanf ("%s",&s); if(s[0]=='A') {sq++; scanf ("%d%d%d",&q[sq].p.x,&q[sq].p.y,&q[sq].p.z); Q[sq].id=sq;q[sq].t=1; stk[++top]=Q[SQ].P; } if(s[0]=='C') {sq++; Q[SQ].P=stk[top--]; Q[sq].id=sq;q[sq].t=-1; } if(s[0]=='Q') {sq++; scanf ("%d%d%d%d",&q[sq].p.x,&q[sq].p.y,&q[sq].p.z,&Q[SQ].R); Q[sq].id=sq;q[sq].t=0; } }}BOOLCmp (Query a,query b) {returna.p.x<b.p.x| | a.p.x==b.p.x&&a.t<b.t;}intLower_bound (intLintRintx) {if(x<y[1])return 1; while(l<r) {intmid=l+r+1>>1; if(y[mid]>x) r=mid-1;ElseL=mid; } returnL +1;}voidFix () {inti; Sort (a+1, a+sh+1, CMP); Sy=0; Rep (I,1, SH)if(a[i].t<2) y[++sy]=a[i].p.y; Sort (y+1, y+sy+1); Sy=unique (y+1, y+sy+1)-(y+1); Rep (I,1, sy+1) rt[i]=0; tcnt=0; Rep (I,1, SH) { if(a[i].t<2) Add (Lower_bound (1, SY,A[I].P.Y), a[i].p.z,a[i].t); Else { intL=lower_bound (1, sy,a[i].p.y-1), R=lower_bound (1, sy,a[i].p.y+A[I].R); if(L==R)Continue; Ans[a[i].id]+ = (get_sum (R,A[I].P.Z,A[I].R)-get_sum (L,A[I].P.Z,A[I].R)) * (a[i].t-3); } }}BOOLIn (Point A,point B,intr) {returna.x>=b.x&&a.y>=b.y&&a.z>=b.z&&a.x<=b.x+r&&a.y<=b.y+r&& a.z<=b.z+R;}voidWork (intLintr) {intso=0, sa=0, I,j; Rep (I,l,r)if(!q[i].t) sa++;Elseso++; if(!sa| |! Soreturn; if(r-l+1<= -) {Rep (i,l,r-1) Rep (j,i+1, R)if(!q[j].t&&in (Q[I].P,Q[J].P,Q[J].R)) ans[q[j].id]+=q[i].t; return; } intMid=l+r>>1; if(l==1&&R==SQ) mid=N; Work (L,MID); Work (Mid+1, R); SH=0; Rep (I,l,mid)if(q[i].t!=0) a[++sh]=Q[i]; inths=sh; Rep (I,mid+1, R)if(!q[i].t) {a[++sh]=q[i];a[sh].p.x--;a[sh].t=2; a[++sh]=q[i];a[sh].p.x+=q[i].r;a[sh].t=4; } if(hs&&sh>HS) Fix ();}voidPrint () {inti; Rep (I,1, sq)if(!q[i].t) printf ("%d\n", Ans[q[i].id]);}intMain () {Init (); Work (1, SQ); Print ();}
View Code
[CDQ Division] [Treap] [Tree-like array] Theresa and data structure