bzoj4066: 简单题

来源:互联网 发布:手机有些软件打不开 编辑:程序博客网 时间:2024/06/10 03:36

这是一道KD-tree裸题,空间20M。

KD-tree插入点可能会导致树不平衡,使层数过高TLE,因此可以使用替罪羊树暴力重构的思想,同时由于查询较慢,平衡因子可适当减小,具体见代码。另外还有一种每插入若干点暴力重构全树的方法,但好像有点慢?

#include<iostream>#include<cstdio>#include<algorithm>#define N 200005#define B 0.63using namespace std;int n,p,Ans,D,Q[4],Rt,m,cnt,h[N];struct KD_node{int d[2],Mx[2],Mn[2],size,sum,ls,rs,val;}T[N];int R(){char c=getchar();int x=0;while(c<'0'||c>'9')c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x;}void Min(int &x,int &y){if(y<x)x=y;}void Max(int &x,int &y){if(y>x)x=y;}bool cmp(const int &x,const int &y){return T[x].d[D]<T[y].d[D];}void update(int k){int l=T[k].ls,r=T[k].rs;T[k].sum=T[l].sum+T[r].sum+T[k].val;T[k].size=T[l].size+T[r].size+1;for (int i=0;i<2;i++){if(l)Max(T[k].Mx[i],T[l].Mx[i]),Min(T[k].Mn[i],T[l].Mn[i]);if(r)Max(T[k].Mx[i],T[r].Mx[i]),Min(T[k].Mn[i],T[r].Mn[i]);}}void build(int &k,int l,int r,int now){int mid=(l+r)>>1;D=now;nth_element(h+l,h+mid,h+r+1,cmp);k=h[mid];T[k].sum=T[k].val;for (int i=0;i<2;i++)T[k].Mx[i]=T[k].Mn[i]=T[k].d[i];if (l<mid) build(T[k].ls,l,mid-1,now^1);if (r>mid) build(T[k].rs,mid+1,r,now^1);update(k);}void del(int &k){if (!k) return;h[++cnt]=k;del(T[k].ls);del(T[k].rs);k=0;}void rebuild(int &k,int now){h[cnt=1]=++m;T[m].size=1;for (int i=0;i<2;i++)T[m].d[i]=T[m].Mx[i]=T[m].Mn[i]=Q[i];T[m].sum=T[m].val=Q[2];del(k);build(k,1,cnt,now);}void ins(int &k,int now){if (!k){k=++m;T[k].size=1;for (int i=0;i<2;i++)T[k].d[i]=T[k].Mx[i]=T[k].Mn[i]=Q[i];T[k].sum=T[k].val=Q[2];return;}if (Q[now]<T[k].d[now])if (T[T[k].ls].size>T[k].size*B) rebuild(k,now);else ins(T[k].ls,now^1);elseif (T[T[k].rs].size>T[k].size*B) rebuild(k,now);else ins(T[k].rs,now^1);update(k);}bool inter(int k){if (!k) return 0;return Q[0]<=T[k].Mx[0]&&T[k].Mn[0]<=Q[2]&&Q[1]<=T[k].Mx[1]&&T[k].Mn[1]<=Q[3];}void qry(int k){if (Q[0]<=T[k].Mn[0]&&T[k].Mx[0]<=Q[2]&&Q[1]<=T[k].Mn[1]&&T[k].Mx[1]<=Q[3]){Ans+=T[k].sum;return;}if (Q[0]<=T[k].d[0]&&T[k].d[0]<=Q[2]&&Q[1]<=T[k].d[1]&&T[k].d[1]<=Q[3])Ans+=T[k].val;if (inter(T[k].ls)) qry(T[k].ls);if (inter(T[k].rs)) qry(T[k].rs);}int main(){for (n=R(),p=R();p!=3;p=R()){if (p==1) Q[0]=R()^Ans,Q[1]=R()^Ans,Q[2]=R()^Ans,ins(Rt,0);else Q[0]=R()^Ans,Q[1]=R()^Ans,Q[2]=R()^Ans,Q[3]=R()^Ans,Ans=0,qry(Rt),printf("%d\n",Ans);}return 0;}


1 0