The outer layer maintains the weight segment tree, and the inner maintenance kd-tree.
When modified only to the right son inserted, unbalanced when the scapegoat-style reconstruction.
Query when the outer layer of the line segment tree, in the inner layer Kd-tree query the number of points within the rectangle.
Time Complexity $o (Q\log V (\log^2q+\sqrt{q})) $.
#include <cstdio> #include <algorithm> #include <cmath>using namespace Std;const double A=0.8;const int n=50010,m=1600010;inline void Read (int&a) {char c;while (! ((C=getchar ()) >= ' 0 ') && (c<= ' 9 ')); a=c-' 0 '; while (((C=getchar ()) >= ' 0 ') && (c<= ' 9 ')) (a*= Ten) +=c-' 0 ';} int n,ans,cmp_d,op,x1,y1,x2,y2,k;int tmp[n],deep,need[n],cnt,cur;int t[m],l[m],r[m],tot=1;struct node{int d[2],l,r, Max[2],min[2],size;} t[m];inline BOOL CMP (int a,int b) {return t[a].d[cmp_d]<t[b].d[cmp_d];} inline void Umax (Int&a,int b) {if (a<b) a=b;} inline void Umin (Int&a,int b) {if (a>b) a=b;} inline void up (int x) {t[x].size=1+t[t[x].l].size+t[t[x].r].size; if (T[X].L) {UMAX (t[x]. MAX[0],T[T[X].L]. Max[0]); Umin (T[x]. MIN[0],T[T[X].L]. Min[0]); UMAX (T[x]. MAX[1],T[T[X].L]. MAX[1]); Umin (T[x]. MIN[1],T[T[X].L]. MIN[1]); } if (T[X].R) {UMAX (t[x]. MAX[0],T[T[X].R]. Max[0]); Umin (T[x]. MIN[0],T[T[X].R]. Min[0]); UMAX (T[x]. MAX[1],T[T[X].R]. MAX[1]); Umin (T[x]. Min[1],t[t[x].R]. MIN[1]); }}int Build (int l,int r,int D) {int mid= (L+R) >>1; Cmp_d=d; Nth_element (NEED+L+1,NEED+MID+1,NEED+R+1,CMP); int X=need[mid]; T[X]. MAX[0]=T[X]. MIN[0]=T[X].D[0]; T[X]. MAX[1]=T[X]. MIN[1]=T[X].D[1]; if (l!=mid) T[x].l=build (l,mid-1,! D); else t[x].l=0; if (r!=mid) T[x].r=build (mid+1,r,! D); else t[x].r=0; Up (x); return x;} void Dfs (int x) {if (x) Need[++cnt]=x,dfs (T[X].L), DFS (T[X].R);} inline void ins (Int&root,int now) {if (!root) {Root=now;return;} for (int d=deep=0,x=root;;D ^=1) {tmp[++deep]=x; UMAX (T[x]. Max[0],t[now]. Max[0]); UMAX (T[x]. Max[1],t[now]. MAX[1]); Umin (T[x]. Min[0],t[now]. Min[0]); Umin (T[x]. Min[1],t[now]. MIN[1]); t[x].size++; if (T[now].d[d]>=t[x].d[d]) {if (!T[X].R) {t[x].r=now;break;} else X=T[X].R; }else{if (!T[X].L) {t[x].l=now;break;} else X=T[X].L; }} Tmp[++deep]=now; if (Deep<log (t[root].size)/log (1/a)) return; while (double) t[t[now].l].size<a*t[now].size&& (double) t[t[now].r].size<a*t[now].size) now=tmp[--deep]; if (!now) return; if (now==root) {Cnt=0,dfs (root); Root=build (1,cnt,0); Return } int Y=tmp[--deep]; Cnt=0,dfs (now); int K=build (1,cnt,deep&1); if (t[y].l==now) T[y].l=k;else t[y].r=k;} void ask (int x) {if (!x| | T[X]. max[0]<x1| | T[X]. min[0]>x2| | T[X]. max[1]<y1| | T[X]. min[1]>y2| | ANS>=K) return; if (T[x]. MIN[0]>=X1&&T[X]. MAX[0]<=X2&&T[X]. MIN[1]>=Y1&&T[X]. Max[1]<=y2) {Ans+=t[x].size;return;} if (t[x].d[0]>=x1&&t[x].d[0]<=x2&&t[x].d[1]>=y1&&t[x].d[1]<=y2) ans++; Ask (T[X].L); ask (T[X].R);} inline void Add () {int x=1,a=1,b=1000000000,mid,flag=1; while (1) {if (flag) {cur++; T[cur]. Max[0]=t[cur]. min[0]=t[cur].d[0]=x1; T[cur]. Max[1]=t[cur]. Min[1]=t[cur].d[1]=y1; t[cur].size=1; Ins (t[x],cur); } if (a==b) return; Mid= (a+b) >>1; if (K<=mid) {if (!l[x]) L[x]=++tot; x=l[x],b=mid,flag=0; }else{if (!r[x]) R[x]=++tot; X=r[x],a=mid+1, flag=1; }}}inline void Query () {ans=0,ask (t[1]); if (ans<k) {puts ("naive! Orzzyz. "); ans=0; Return } int x=1,a=1,b=1000000000,mid; while (a<b) {mid= (a+b) >>1; Ans=0,ask (T[r[x]); if (ans>=k) X=r[x],a=mid+1;else K-=ans,x=l[x],b=mid; } printf ("%d\n", Ans=a);} int main () {read (n), read (n); while (n--) {Read (OP), read (X1), read (Y1); X1^=ans,y1^=ans; if (op==1) {read (k); K^=ans; Add (); }else{Read (X2), read (Y2), read (k); X2^=ans; Y2^=ans;k^=ans; Query (); }} return 0;}
BZOJ4605: Laoshan white flower snake grass water