BZOJ4066 简单题(KD-Tree)

  板子题。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cassert>
using namespace std;
#define ll long long
#define N 200010
#define inf 2000000000
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
int n,m,root,cnt,c,ans,t,tot,id[N];
const double alpha=0.75; 
struct point
{
    int d[2],v;
    bool operator <(const point&a) const
    {
        return d[c]<a.d[c];
    }
}a[N];
struct KDTree{int ch[2],a[2][2],size,sum;point p;
}tree[N];
inline bool isin(point p,int a[2][2]){return p.d[0]>=a[0][0]&&p.d[0]<=a[0][1]&&p.d[1]>=a[1][0]&&p.d[1]<=a[1][1];}
inline bool isin(int a[2][2],int b[2][2]){return a[0][0]>=b[0][0]&&a[0][1]<=b[0][1]&&a[1][0]>=b[1][0]&&a[1][1]<=b[1][1];}
inline bool iscross(int a[2][2],int b[2][2]){return max(a[0][0],b[0][0])<=min(a[0][1],b[0][1])&&max(a[1][0],b[1][0])<=min(a[1][1],b[1][1]);}
void newnode(int k,point p)
{
    tree[k].size=1,tree[k].sum=p.v,tree[k].p=p;
    tree[k].a[0][0]=tree[k].a[0][1]=p.d[0],tree[k].a[1][0]=tree[k].a[1][1]=p.d[1];
    lson=rson=0;
}
void get(int k)
{
    if (lson) get(lson);
    t++,id[t]=k,a[t]=tree[k].p;
    if (rson) get(rson);
}
void build(int &k,int l,int r,int op)
{
    if (l>r) return;
    c=op;
    int mid=l+r>>1;
    nth_element(a+l,a+mid,a+r+1);
    newnode(k=id[++tot],a[mid]);
    for (int i=l;i<=r;i++)
    tree[k].a[0][0]=min(tree[k].a[0][0],a[i].d[0]),tree[k].a[0][1]=max(tree[k].a[0][1],a[i].d[0]),
    tree[k].a[1][0]=min(tree[k].a[1][0],a[i].d[1]),tree[k].a[1][1]=max(tree[k].a[1][1],a[i].d[1]);
    build(lson,l,mid-1,op^1),build(rson,mid+1,r,op^1);
    tree[k].size+=tree[lson].size,tree[k].size+=tree[rson].size,
    tree[k].sum+=tree[lson].sum,tree[k].sum+=tree[rson].sum;
}
void rebuild(int &k,int op)
{
    t=0;get(k);
    tot=0;build(k,1,t,op);
}
void ins(int &k,point p,int op)
{
    if (!k) {newnode(k=++cnt,p);return;}
    if (max(tree[lson].size,tree[rson].size)>tree[k].size*alpha) rebuild(k,op);
    tree[k].size++;tree[k].sum+=p.v;
    tree[k].a[0][0]=min(tree[k].a[0][0],p.d[0]),tree[k].a[0][1]=max(tree[k].a[0][1],p.d[0]);
    tree[k].a[1][0]=min(tree[k].a[1][0],p.d[1]),tree[k].a[1][1]=max(tree[k].a[1][1],p.d[1]);
    if (tree[k].a[op][1]<=p.d[0]) ins(lson,p,op^1);
    else ins(rson,p,op^1);
}
int query(int k,int a[2][2])
{
    if (!k) return 0;
    if (isin(tree[k].a,a)) return tree[k].sum;
    return (isin(tree[k].p,a)?tree[k].p.v:0)+
    (iscross(tree[lson].a,a)?query(lson,a):0)+
    (iscross(tree[rson].a,a)?query(rson,a):0);
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("bzoj4066.in","r",stdin);
    freopen("bzoj4066.out","w",stdout);
    const char LL[]="%I64d\n";
#else
    const char LL[]="%lld\n";
#endif
    read();int op=read();
    while (op<3)
    {
        if (op==1)
        {
            int x=read()^ans,y=read()^ans,z=read()^ans;
            ins(root,(point){{x,y},z},0);
        }
        else
        {
            int a[2][2];a[0][0]=read()^ans,a[1][0]=read()^ans,a[0][1]=read()^ans,a[1][1]=read()^ans;
            printf("%d\n",ans=query(root,a));
        }
        op=read();
    }
    return 0;
}

 

posted @ 2018-12-22 16:07  Gloid  阅读(118)  评论(0编辑  收藏  举报