Meaning of the questions: is now given to the three-dimensional plane empty, a plus point operation and ask cube points.
Ideas: Consider CDQ sets of CDQ. Complexity is O (NlogN * logN * logN) , can lead to this problem.
Specifically, it is a problem of four-dimensional partial order, are four-dimensional (times, x, y, z); We know cdq can be calculated t <= T, x = X, y <= Y, in a layer on the sleeve can z <= Z a. So a cube, we split into eight points inclusion and exclusion.
The question now is then obtained (0,0,0) to the point (x, y, z) of. The first dimension T has a default sort, we first X partition. All the problems into two, and the left side of this mark o = -1, the right tag o = 1, then the normal CDQ stuffed inside the partition to be y, z for statistics. At this time, to insert a tree z array, especially to meet the needs o = -1; satisfies the query requires extra o = 1;
For CDQ: After the first dimension of a partition between two cells out after, merge sort on it, so to avoid the sort. Here can also be used for the convenience of inplace_merge, but slower than some of the handwriting.
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=400010; struct in{ int x,y,z,id,opt,o; //编号,正负,第一维是否在左 }s[maxn],q[maxn],fcy[maxn]; bool cmp1(in w,in v) { return w.x<v.x;} bool cmp2(in w,in v) { return w.y<v.y;} int b[maxn],sz,tot,cnt,ans[maxn],sum[maxn]; void add(int x,int val) { for(int i=x;i<=sz;i+=(-i)&i) sum[i]+=val; } int query(int x) { int res=0; for(int i=x;i;i-=(-i)&i) res+=sum[i]; return res; } void cdq2(int L,int R) { if(L>=R) return ; int Mid=(L+R)>>1,i=L,j=Mid+1,now; cdq2(L,Mid); cdq2(Mid+1,R); for(;j<=R;j++){ for(;i<=Mid&&q[i].y<=q[j].y;i++){ if(q[i].o==-1&&q[i].opt==0) add(q[i].z,1); } if(q[j].o==1&&q[j].id) ans[q[j].id]+=q[j].opt*query(q[j].z); } while((--i)>=L) if(q[i].o==-1&&!q[i].id) add(q[i].z,-1); /*i=L,j=Mid+1,now=L; 手写归并,下面cdq1同理。 while(j<=R&&i<=Mid){ if(q[i].y<=q[j].y) fcy[now++]=q[i++]; else fcy[now++]=q[j++]; } while(i<=Mid) fcy[now++]=q[i++]; while(j<=R) fcy[now++]=q[j++]; rep(i,L,R) q[i]=fcy[i];*/ inplace_merge(q+L,q+Mid+1,q+R+1,cmp2); //归并排序 } void cdq1(int L,int R) { if(L>=R) return ; int Mid=(L+R)>>1,i=L,j=Mid+1,now=L; cdq1(L,Mid); cdq1(Mid+1,R); //sort(s+L,s+Mid+1,cmp1); sort(s+Mid+1,s+R+1,cmp1); tot=0; while(j<=R&&i<=Mid){ if(s[i].x<=s[j].x){ fcy[now++]=s[i]; q[++tot]=s[i++],q[tot].o=-1; if(s[i-1].id) tot--; } else { fcy[now++]=s[j]; q[++tot]=s[j++],q[tot].o=1; if(!s[j-1].id) tot--; } } while(i<=Mid) { fcy[now++]=s[i]; q[++tot]=s[i++],q[tot].o=-1; if(s[i-1].id) tot--; } while(j<=R) { fcy[now++]=s[j]; q[++tot]=s[j++],q[tot].o=1; if(!s[j-1].id) tot--; } rep(i,L,R) s[i]=fcy[i]; //inplace_merge(s+L,s+Mid+1,s+R+1,cmp1); cdq2(1,tot); } void solve() { int N,Q=0,opt,x1,y1,z1,x2,y2,z2; sz=0; tot=0; scanf("%d",&N); rep(i,1,N){ scanf("%d",&opt); if(opt&1){ scanf("%d%d%d",&x1,&y1,&z1); b[++sz]=z1; s[++tot]=in{x1,y1,z1,0,0,0}; } else { scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2); b[++sz]=z1; b[++sz]=z2; b[++sz]=z1-1; ans[++Q]=0; s[++tot]=in{x2,y2,z2,Q,1,0}; s[++tot]=in{x1-1,y1-1,z1-1,Q,-1,0}; s[++tot]=in{x1-1,y2,z2,Q,-1,0}; s[++tot]=in{x1-1,y1-1,z2,Q,1,0}; s[++tot]=in{x1-1,y2,z1-1,Q,1,0}; s[++tot]=in{x2,y1-1,z2,Q,-1,0}; s[++tot]=in{x2,y2,z1-1,Q,-1,0}; s[++tot]=in{x2,y1-1,z1-1,Q,1,0}; } } sort(b+1,b+sz+1); cnt=unique(b+1,b+sz+1)-(b+1); rep(i,1,tot) s[i].z=lower_bound(b+1,b+sz+1,s[i].z)-b; cdq1(1,tot); rep(i,1,Q) printf("%d\n",ans[i]); } int main() { int T; scanf("%d",&T); while(T--) solve(); return 0; }