sb错误调了两个小时。。。
其实就是K-D tree,然后在不太平衡的时候就暴力重构一下。
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 200005
#define inf 1000000007
using namespace std;
int cunt;
struct node
{
int d[2],mn[2],mx[2];
int size,sum,v,D;
};
node now,tree[N];
int ls[N],rs[N],p[N];
int n,w,D,root,tot,cnt,ans;
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}/*
inline bool cmp(node a,node b)
{
return a.d[D]<b.d[D];
}*/ // 就是这里写错了。。。坑啊。。
inline bool cmp(int a,int b)
{
return tree[a].d[D]<tree[b].d[D];
}
inline void pushup(int k)
{
for (int i=0;i<=1;i++)
{
tree[k].mn[i]=min(tree[k].mn[i],min(tree[ls[k]].mn[i],tree[rs[k]].mn[i]));
tree[k].mx[i]=max(tree[k].mx[i],max(tree[ls[k]].mx[i],tree[rs[k]].mx[i]));
}
tree[k].sum=tree[ls[k]].sum+tree[rs[k]].sum+tree[k].v;
tree[k].size=tree[ls[k]].size+tree[rs[k]].size+1;
}
int build(int &k,int l,int r,int dir)
{
int mid=l+r>>1; D=dir;
nth_element(p+l,p+mid,p+r+1,cmp);
k=p[mid];
tree[k].D=dir;
tree[k].mn[0]=tree[k].mx[0]=tree[k].d[0];
tree[k].mn[1]=tree[k].mx[1]=tree[k].d[1];
tree[k].sum=tree[k].v;
if (l<mid) build(ls[k],l,mid-1,dir^1); else ls[k]=0;
if (r>mid) build(rs[k],mid+1,r,dir^1); else rs[k]=0;
pushup(k);
}
void dfs(int k)
{
if (!k) return;
dfs(ls[k]); p[++tot]=k; dfs(rs[k]);
}
inline void rebuild(int &k)
{
tot=0; dfs(k);
build(k,1,tot,tree[k].D);
}
void insert(int &k,int dir)
{
if (!k)
{
k=++cnt;
tree[k]=now;
tree[k].mn[0]=tree[k].mx[0]=tree[k].d[0];
tree[k].mn[1]=tree[k].mx[1]=tree[k].d[1];
tree[k].sum=tree[k].v; tree[k].size=1;
tree[k].D=dir;
return;
}
if (now.d[dir]<tree[k].d[dir])
{
insert(ls[k],dir^1);
pushup(k);
if ((double)tree[ls[k]].size>(double)tree[k].size*0.7) rebuild(k);
}
else
{
insert(rs[k],dir^1);
pushup(k);
if ((double)tree[rs[k]].size>(double)tree[k].size*0.7) rebuild(k);
}
}
int query(int k,int x1,int y1,int x2,int y2)
{
cunt ++ ;
if (!k) return 0;
int ans=0;
if (tree[k].mn[0]>=x1&&tree[k].mx[0]<=x2&&tree[k].mn[1]>=y1&&tree[k].mx[1]<=y2) return tree[k].sum;
else
{
if (tree[k].d[0]>=x1&&tree[k].d[0]<=x2&&tree[k].d[1]>=y1&&tree[k].d[1]<=y2) ans+=tree[k].v;
if (tree[ls[k]].mn[0]>x2||tree[ls[k]].mx[0]<x1||tree[ls[k]].mn[1]>y2||tree[ls[k]].mx[1]<y1); else ans+=query(ls[k],x1,y1,x2,y2);
if (tree[rs[k]].mn[0]>x2||tree[rs[k]].mx[0]<x1||tree[rs[k]].mn[1]>y2||tree[rs[k]].mx[1]<y1); else ans+=query(rs[k],x1,y1,x2,y2);
return ans;
}
}
int main()
{
// freopen("txt.in","r",stdin);
// freopen("1.out","w",stdout);
tree[0].mn[0]=tree[0].mn[1]=inf;
tree[0].mx[0]=tree[0].mx[1]=-inf;
n=read();
while (scanf("%d",&w)!=EOF&&w!=3)
if (w==1)
{
now.d[0]=read()^ans; now.d[1]=read()^ans; now.v=read()^ans;
// now.d[0]=read(); now.d[1]=read(); now.v=read();
insert(root,1);
}
else
{
int x1=read()^ans,y1=read()^ans,x2=read()^ans,y2=read()^ans;
// int x1=read(),y1=read(),x2=read(),y2=read();
printf("%d\n",ans=query(root,x1,y1,x2,y2));
}
// for (int k=1;k<=10;k++)
// printf("%d %d %d %d %d %d\n",tree[k].sum,tree[k].D,tree[k].mx[0],tree[k].mx[1],tree[k].mn[0],tree[k].mn[1]);
cout << cunt;
return 0;
}