Code:
// luogu-judger-enable-o2 // luogu-judger-enable-o2 #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) //,freopen(s".out","w",stdout) struct Data { int ch[2],w,minv[2],maxv[2],p[2],siz,sum; }node[20000000], arr[20000000]; namespace KDtree { #define maxn 20000000 #define Min(a,b) (a = a>b?b:a) #define Max(a,b) (a = b>a?b:a) int d,c_arr; std::queue<int>Q; void Init() { for(int i=1;i<maxn;++i) Q.push(i); } int newnode(){ int q = Q.front(); Q.pop(); return q; } bool cmp(Data i,Data j) { return i.p[d]==j.p[d]?i.p[d^1]<j.p[d^1]:i.p[d]<j.p[d]; } bool isout(int k,int x1,int y1,int x2,int y2) { if(node[k].maxv[0]<x1||node[k].minv[0]>x2||node[k].maxv[1]<y1||node[k].minv[1]>y2) return 1; return 0; } bool isin(int k,int x1,int y1,int x2,int y2) { if(node[k].maxv[0]<=x2 && node[k].minv[0]>=x1&&node[k].maxv[1]<=y2&&node[k].minv[1]>=y1) return 1; return 0; } void pushup(int x,Data p) { node[x].sum+=p.sum; node[x].siz+=p.siz; Min(node[x].minv[0],p.minv[0]); Min(node[x].minv[1],p.minv[1]); Max(node[x].maxv[0],p.maxv[0]); Max(node[x].maxv[1],p.maxv[1]); } int query(int x,int x1,int y1,int x2,int y2) { if(!x||isout(x,x1,y1,x2,y2)) return 0; if(isin(x,x1,y1,x2,y2)) { return node[x].sum; } int ans=0; if(node[x].p[0]>=x1&&node[x].p[0]<=x2&&node[x].p[1]>=y1&&node[x].p[1]<=y2) ans=1; ans += query(node[x].ch[0],x1,y1,x2,y2)+query(node[x].ch[1],x1,y1,x2,y2); return ans; } void dfs(int &o) { if(!o) return; dfs(node[o].ch[0]); arr[++c_arr] = node[o]; arr[c_arr].sum=arr[c_arr].w=1; arr[c_arr].maxv[0]=arr[c_arr].minv[0]=arr[c_arr].p[0]; arr[c_arr].maxv[1]=arr[c_arr].minv[1]=arr[c_arr].p[1]; arr[c_arr].siz=1; Q.push(o); dfs(node[o].ch[1]); o=0; } void rebuild(int &x,int l,int r,int o) { int mid=(l+r)>>1; d=o,std::nth_element(arr+l,arr+mid,arr+1+r,cmp); x=newnode(); node[x]=arr[mid]; node[x].minv[0]=node[x].maxv[0]=node[x].p[0]; node[x].minv[1]=node[x].maxv[1]=node[x].p[1]; node[x].sum=node[x].w=1; node[x].ch[0]=node[x].ch[1]=0; node[x].siz=1; if(l<mid) rebuild(node[x].ch[0],l,mid-1,o^1), pushup(x, node[node[x].ch[0]]); if(r>mid) rebuild(node[x].ch[1],mid+1,r,o^1), pushup(x, node[node[x].ch[1]]); } void Reconstruct(int &u) { c_arr=0; dfs(u); rebuild(u,1,c_arr,d=0); } bool check(int son,int x) { if(son*10>x*9) return true; return false; } void insert(int &x,Data a,int de,int tag) { if(!x) { x=newnode(); node[x].p[0]=node[x].maxv[0]=node[x].minv[0]=a.p[0]; node[x].p[1]=node[x].maxv[1]=node[x].minv[1]=a.p[1]; node[x].sum=node[x].w=1; node[x].siz=1,node[x].ch[0]=node[x].ch[1]=0; return; } d = de; int is=0; if(cmp(a,node[x]) == 1) { is = check(node[node[x].ch[0]].siz+1,node[x].siz+1); insert(node[x].ch[0],a,de^1,is||tag); pushup(x,a); } //a is bigger (rson) else { is = check(node[node[x].ch[1]].siz+1,node[x].siz+1); insert(node[x].ch[1],a,de^1,is||tag); pushup(x,a); } if(tag && is) Reconstruct(x); } }; #define y1 opopopop int lson[2000000],rson[2000000],rt[2000000]; int x1,y1,x2,y2, tot=0,root=0; void modify(int &x,int l,int r,int k,Data i) { if(!x) x = ++tot; KDtree::insert(rt[x],i,0,0); if(l==r) return; int mid = (l+r)>>1; if(k <= mid) modify(lson[x],l,mid,k,i); else modify(rson[x],mid+1,r,k,i); } int query(int x,int l,int r,int kth) { if(l==r) return l; int u = KDtree::query(rt[rson[x]],x1,y1,x2,y2); int mid = (l + r) >> 1; if(u < kth) return query(lson[x],l,mid,kth-u); else return query(rson[x],mid+1,r,kth); } int Query(int kth) { return query(root,0,1000000000,kth); } int n,q,lastans=0; int main() { // setIO("input"); KDtree::Init(); scanf("%d%d",&n,&q); for(int cc=1;cc<=q;++cc) { int opt,a,b,c,d; scanf("%d",&opt); if(opt==1) { scanf("%d%d%d",&a,&b,&c); a^=lastans,b^=lastans,c^=lastans; Data f; f.p[0]=f.maxv[0]=f.minv[0]=a; f.p[1]=f.maxv[1]=f.minv[1]=b; f.ch[0]=f.ch[1]=0; f.siz=1; f.sum=f.w=1; modify(root,0,1000000000,c,f); } if(opt==2) { scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&a); x1^=lastans,y1^=lastans,x2^=lastans,y2^=lastans,a^=lastans; lastans = Query(a); if(lastans==0) printf("NAIVE!ORZzyz.\n"); else printf("%d\n",lastans); } } return 0; }
原文:https://www.cnblogs.com/guangheli/p/10959473.html