Offline all operations, the establishment of all possible points kd-tree,add equivalent to the weight of +1,cancel equivalent weight-1.
The modification operation is to record the FA for each point on the kd-tree and modify it from the bottom up.
Optimization: If the sumv==0 of a rectangle box is not entered. The area of the rectangle is recorded with only "meaningful" points (with a weight of 0 regardless of the value).
#include <cstdio> #include <algorithm> #include <stack> #include <cstring>using namespace std; int f,c;inline void R (int &x) {c=0;f=1; for (; c< ' 0 ' | | C> ' 9 '; C=getchar ()) if (c== '-') f=-1; for (x=0; c>= ' 0 ' &&c<= ' 9 '; C=getchar ()) (x*=10) + = (c ' 0 '); X*=f;} inline void P (int x) {if (x<10) putchar (x+ ' 0 '); Else{p (X/10);p Utchar (x%10+ ' 0 ');}} stack<int>zhan; #define N 100001#define KD 3int dn,n,root,m,qp[2][kd],idn;struct node{int ch[2],w,minn[kd],maxx[ Kd],p[kd],sumv,id; void Init () {sumv=w; for (int i=0;i<kd;++i) minn[i]=maxx[i]=p[i]; }}t[n];bool operator < (const node &a,const node &b) {return A.P[DN] < B.P[DN];} inline void pushup (const int &rt) {T[RT].SUMV=T[RT].W; for (int i=0;i<2;++i) if (t[rt].ch[i]/* && t[t[rt].ch[i]].sumv*/) {t[rt].sumv+=t[t[rt].ch[i ]].SUMV; for (int j=0;j<kd;++j) {t[rt].minn[j]=min (T[RT].MINN[J],T[T[RT].CH[I]].MINN[J]); T[rt].maxx[j]=max (T[rt].maxx[j],t[t[rt].ch[i]].maxx[j]); }}}int buildtree (int l=1,int r=n,int d=0) {dn=d; int m= (l+r>>1); Nth_element (t+l,t+m,t+r+1); T[M]. Init (); if (l!=m) T[m].ch[0]=buildtree (L,m-1, (d+1)%KD); if (m!=r) T[m].ch[1]=buildtree (M+1,r, (d+1)%KD); Pushup (m); return m;} inline bool Inside (const int &o) {for (int i=0;i<kd;++i) if (Qp[0][i] > T[o].p[i] | | T[o].p[i] > Qp[1][i]) return 0; return 1;} inline bool Allinside (const int &o) {for (int i=0;i<kd;++i) if (Qp[0][i] > T[o].minn[i] | | T[o].maxx[i] > Qp[1][i]) return 0; return 1;} inline bool Cross (const int &o) {for (int i=0;i<kd;++i) if (Qp[0][i] > T[o].maxx[i] | | T[o].minn[i] > Qp[1][i]) return 0; return 1;} int ans;inline void Query (int rt=root) {if (Inside (RT)) ANS+=T[RT].W; for (int i=0;i<2;++i) if (T[rt].ch[i] && cross (T[rt].ch[i]) {if (Allinside (T[rt].ch[i])) ANS+=T[T[RT].CH[I]].SUMV; else if (T[T[RT].CH[I]].SUMV) Query (T[rt].ch[i]); }}int Val;char op[n][7];int dian[n][kd],rs[n],ids[n],ma[n],fa[n];void Update () {int u=ma[idn]; T[u].w+=val; T[u].sumv+=val; U=fa[u]; while (u) {t[u].sumv=t[u].w+t[t[u].ch[0]].sumv+t[t[u].ch[1]].sumv;//pushup (U); U=fa[u]; }}int Main () {//Freopen ("Theresa9.in", "R", stdin);//Freopen ("Bzoj3290.out", "w", stdout); R (n); for (int i=1;i<=n;++i) {R (t[i].p[0]); R (t[i].p[1]); R (t[i].p[2]); T[i].id=i; T[i].w=1; } R (M); for (int i=1;i<=m;++i) {scanf ("%s", Op[i]); if (op[i][0]== ' A ') {++n; R (T[n].p[0]); R (t[n].p[1]); R (t[n].p[2]); T[n].id=n; Ids[i]=n; Zhan.push (n); } else if (op[i][0]== ' Q ') {R (dian[i][0]); R (dian[i][1]); R (Dian[i][2]); R (Rs[i]); } else {ids[i]=zhan.top (); Zhan.pop (); }} root= (1+n>>1); Buildtree (); for (int i=1;i<=n;++i) {ma[t[i].id]=i; for (int j=0;j<2;++j) if (t[i].ch[j]) fa[t[i].ch[j]]=i; } for (int i=1;i<=m;++i) if (op[i][0]== ' A ') {idn=ids[i]; val=1; Update (); } else if (op[i][0]== ' Q ') {memcpy (qp[0],dian[i],sizeof (qp[0])); for (int j=0;j<kd;++j) qp[1][j]=qp[0][j]+rs[i]; ans=0; Query ();//printf ("%d\n", ans); P (ANS), puts (""); } else {idn=ids[i]; Val=-1; Update (); } return 0;}
"Kd-tree" bzoj3290 Theresa and data structures