˼·
强制在线。k-dtree。
卡常啊。空间开1e6就T了。
#include <bits/stdc++.h> #define my_min(a,b) (a<b?a:a=b) #define my_max(a,b) (a>b?a:a=b) using namespace std; const double alpha=0.75; const int N=2e5+7; int read() { int x=0,f=1; char s=getchar(); for(; s>'9'||s<'0'; s=getchar()) if(s=='-') f=-1; for(; s>='0'&&s<='9'; s=getchar()) x=x*10+s-'0'; return x*f; } int WD,lastans; struct point { int x[2],v; bool operator < (const point &b) const { return x[WD]<b.x[WD]; } } p[N]; struct node { int ls,rs,mi[2],ma[2],sum,siz; point a; } e[N]; int rub[N],top,cnt; int newnode() { if(top) return rub[top--]; return ++cnt; } void update(int x,int y) { my_min(e[x].mi[0],e[y].mi[0]); my_min(e[x].mi[1],e[y].mi[1]); my_max(e[x].ma[0],e[y].ma[0]); my_max(e[x].ma[1],e[y].ma[1]); } void up(int u) { int ls=e[u].ls,rs=e[u].rs; e[u].mi[0]=e[u].ma[0]=e[u].a.x[0]; e[u].mi[1]=e[u].ma[1]=e[u].a.x[1]; e[u].sum=e[ls].sum+e[rs].sum+e[u].a.v; e[u].siz=e[ls].siz+e[rs].siz+1; if(ls) update(u,ls); if(rs) update(u,rs); } int build(int l,int r,int wd) { if(l>r) return 0; int mid=(l+r)>>1; WD=wd; nth_element(p+l,p+mid,p+r+1); int u=newnode(); e[u].a=p[mid]; e[u].ls=build(l,mid-1,wd^1); e[u].rs=build(mid+1,r,wd^1); up(u); return u; } void pia(int u,int num) { if(e[u].ls) pia(e[u].ls,num); p[num+e[e[u].ls].siz+1]=e[u].a; rub[++top]=u; if(e[u].rs) pia(e[u].rs,num+e[e[u].ls].siz+1); } int check(int &u,int wd) { if(alpha*e[u].siz<e[e[u].ls].siz||alpha*e[u].siz<e[e[u].rs].siz) pia(u,0),u=build(1,e[u].siz,wd); } void insert(point a,int &rt,int wd) { if(!rt) { rt=newnode(); e[rt].a=a; e[rt].ls=e[rt].rs=0; up(rt); return; } if(e[rt].a.x[wd]<a.x[wd]) insert(a,e[rt].rs,wd^1); else insert(a,e[rt].ls,wd^1); up(rt); check(rt,wd); } int pd(node a,int x,int y,int X,int Y) { if(x<=a.mi[0]&&a.ma[0]<=X&&y<=a.mi[1]&&a.ma[1]<=Y) return 1; if(a.ma[0]<x||X<a.mi[0]) return 0; if(a.ma[1]<y||Y<a.mi[1]) return 0; return 2; } void query(int rt,int x,int y,int X,int Y) { if(x<=e[rt].a.x[0]&&e[rt].a.x[0]<=X &&y<=e[rt].a.x[1]&&e[rt].a.x[1]<=Y) lastans+=e[rt].a.v; int ls=e[rt].ls,rs=e[rt].rs; if(ls) { int PD=pd(e[ls],x,y,X,Y); if(PD==1) lastans+=e[ls].sum; if(PD==2) query(ls,x,y,X,Y); } if(rs) { int PD=pd(e[rs],x,y,X,Y); if(PD==1) lastans+=e[rs].sum; if(PD==2) query(rs,x,y,X,Y); } } int main() { int rt=0,n=read(); while(233) { int opt=read(); if(opt==1) { point a; a.x[0]=read()^lastans,a.x[1]=read()^lastans,a.v=read()^lastans; insert(a,rt,0); } else if(opt==2) { int x=read()^lastans,y=read()^lastans,X=read()^lastans,Y=read()^lastans; lastans=0; query(rt,x,y,X,Y); printf("%d\n",lastans); } else break; } return 0; }