Gary88 @ 2020-12-30 23:31:41
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define p 0.75
using namespace std;
int n,rt,lastans,tot,num,a[1000001];
queue<int>q;
struct node
{
int ch[2],tch,tot,f,U,D,L,R,mode;
}t[1000001];
struct pp
{
int x,y,sz;
}s[1000001];
bool cmp1(int aa,int bb)
{
return s[aa].x<s[bb].x;
}
bool cmp2(int aa,int bb)
{
return s[aa].y<s[bb].y;
}
void pushup(int x)
{
t[x].tch=t[t[x].ch[0]].tch+t[t[x].ch[1]].tch+1;
t[x].tot=t[t[x].ch[1]].tot+t[t[x].ch[0]].tot+s[x].sz;
t[x].U=t[x].D=s[x].y;
t[x].L=t[x].R=s[x].x;
if(t[x].ch[0])
{
t[x].U=max(t[x].U,t[t[x].ch[0]].U),t[x].D=min(t[x].D,t[t[x].ch[0]].D);
t[x].R=max(t[x].R,t[t[x].ch[0]].R),t[x].L=min(t[x].L,t[t[x].ch[0]].L);
}
if(t[x].ch[1])
{
t[x].U=max(t[x].U,t[t[x].ch[1]].U),t[x].D=min(t[x].D,t[t[x].ch[1]].D);
t[x].R=max(t[x].R,t[t[x].ch[1]].R),t[x].L=min(t[x].L,t[t[x].ch[1]].L);
}
}
void divide(int x)
{
if(!x)
return;
divide(t[x].ch[0]);
a[++tot]=x;
divide(t[x].ch[1]);
}
int build(int l,int r,int fa)
{
if(l>r)
return 0;
double avx=0,avy=0,vax=0,vay=0;
for(int i=l;i<=r;i++)
{
avx+=s[a[i]].x;
avy+=s[a[i]].y;
}
avx/=double(r-l+1);
avx/=double(r-l+1);
for(int i=l;i<=r;i++)
{
vax+=(avx-s[a[i]].x)*(avx-s[a[i]].x);
vay+=(avy-s[a[i]].y)*(avy-s[a[i]].y);
}
int mid=(l+r)>>1;
if(vax>=vay)
{
nth_element(a+l,a+mid,a+r+1,cmp1);
t[a[mid]].mode=1;
}
else
{
nth_element(a+l,a+mid,a+r+1,cmp2);
t[a[mid]].mode=2;
}
t[a[mid]].f=fa;
t[a[mid]].ch[0]=build(l,mid-1,a[mid]),t[a[mid]].ch[1]=build(mid+1,r,a[mid]);
pushup(a[mid]);
return a[mid];
}
bool need_rebuild(int x)
{
return ((double(max(t[t[x].ch[0]].tch,t[t[x].ch[1]].tch)))/(double(t[x].tch)))>=p;
}
int find_rebuild(int x)
{
if(t[x].f)
{
int k=find_rebuild(t[x].f);
if(k)
return k;
}
if(need_rebuild(x))
return x;
else
return 0;
}
void update(int x)
{
if(!x)
return;
t[x].tch=t[t[x].ch[0]].tch+t[t[x].ch[1]].tch+1;
t[x].tot=t[t[x].ch[1]].tot+t[t[x].ch[0]].tot+s[x].sz;
t[x].U=t[x].D=s[x].y;
t[x].L=t[x].R=s[x].x;
if(t[x].ch[0])
{
t[x].U=max(t[x].U,t[t[x].ch[0]].U),t[x].D=min(t[x].D,t[t[x].ch[0]].D);
t[x].R=max(t[x].R,t[t[x].ch[0]].R),t[x].L=min(t[x].L,t[t[x].ch[0]].L);
}
if(t[x].ch[1])
{
t[x].U=max(t[x].U,t[t[x].ch[1]].U),t[x].D=min(t[x].D,t[t[x].ch[1]].D);
t[x].R=max(t[x].R,t[t[x].ch[1]].R),t[x].L=min(t[x].L,t[t[x].ch[1]].L);
}
update(t[x].f);
}
int find(int x,int y)
{
int u=rt;
while(s[u].x!=x||s[u].y!=y)
{
if(t[u].mode==1)
{
if(t[u].ch[s[u].x<x])
u=t[u].ch[s[u].x<x];
else
return u;
}
else if(t[u].mode==2)
{
if(t[u].ch[s[u].y<y])
u=t[u].ch[s[u].y<y];
else
return u;
}
else
return u;
}
}
void insert(int x,int y,int z)
{
if(!rt)
{
int K=num;
rt=K;
t[K].tot=z;
t[K].tch=1;
update(K);
return;
}
int u=find(x,y);
if(s[u].x==x&&s[u].y==y)
{
s[u].sz+=z;
num--;
update(u);
}
else
{
int kk=num;
if(t[u].mode==1)
{
t[u].ch[s[u].x<x]=kk;
}
else if(t[u].mode==2)
{
t[u].ch[s[u].y<y]=kk;
}
else
{
if(abs(s[u].x-x)<abs(s[u].y-y))
{
t[u].mode=2;
t[u].ch[s[u].y<y]=kk;
}
else
{
t[u].mode=1;
t[u].ch[s[u].x<x]=kk;
}
}
t[kk].f=u;
update(kk);
int k=find_rebuild(kk);
if(k)
{
tot=0;
int y=t[k].f,s=(t[y].ch[1]==k);
divide(k);
int z=build(1,tot,y);
if(y)
t[y].ch[s]=z;
else
rt=z;
update(y);
}
}
}
bool in(int root,int L,int D,int R,int U)
{
return (t[root].R>=L&&t[root].L<=R&&t[root].D<=U&&t[root].U>=D);
}
int ask(int root,int L,int D,int R,int U)
{
if(t[root].L>=L&&t[root].R<=R&&t[root].D>=D&&t[root].U<=U)
{
return t[root].tot;
}
int ans=0;
if(s[root].x>=L&&s[root].x<=R&&s[root].y>=D&&s[root].y<=U)
ans+=s[root].sz;
if(in(t[root].ch[0],L,D,R,U))
ans+=ask(t[root].ch[0],L,D,R,U);
if(in(t[root].ch[1],L,D,R,U))
ans+=ask(t[root].ch[1],L,D,R,U);
return ans;
}
int main()
{
scanf("%d",&n);
int mode;
while(scanf("%d",&mode)&&mode!=3)
{
if(mode==1)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
x^=lastans,y^=lastans,z^=lastans;
s[++num].x=x;
s[num].y=y;
s[num].sz=z;
insert(x,y,z);
}
else
{
int xx,yy,XX,YY;
scanf("%d%d%d%d",&xx,&yy,&XX,&YY);
xx^=lastans,yy^=lastans,XX^=lastans,YY^=lastans;
lastans=ask(rt,xx,yy,XX,YY);
printf("%d\n",lastans);
}
}
return 0;
}
by ADay @ 2020-12-30 23:42:18
重构开销太大吧
by Gary88 @ 2020-12-31 16:47:07
@ADay 我也这么觉得,可我找不到重构在哪里开销大了