萌新刚学OI,求助

P4148 简单题

TiCl4 @ 2019-07-20 22:48:27

我的\texttt{KD Tree}为什么\color{#8e44ad}\texttt{RE \#2,\#3,\#4,\#5}了?

数组开到2\times 10^6都没用。。。

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
const ll MAXN=2e6+51;
const double alpha=0.75;
ll dim;
struct Node{
    ll val; 
    ll d[2];
    inline bool operator <(const Node &rhs)const;
};
struct KDTree{
    Node nd;
    ll sum,size;
    ll minn[2],maxn[2],ch[2];
    inline void clear()
    {
        minn[0]=minn[1]=maxn[0]=maxn[1]=sum=size=nd.d[0]=nd.d[1]=nd.val=0;
    }
};
Node nd[MAXN];
KDTree tree[MAXN];
ll cnt,ptr,ptr2,tot,x,y,xx,yy,z,op,lastAns,rt;
ll pool[MAXN];
inline ll read()
{
    register ll num=0,neg=1;
    register char ch=getchar();
    while(!isdigit(ch)&&ch!='-')
    {
        ch=getchar();
    }
    if(ch=='-')
    {
        neg=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        num=(num<<3)+(num<<1)+(ch-'0');
        ch=getchar();
    }
    return num*neg;
} 
inline void chkmin(ll &x,ll y)
{
    if(x>y)
    {
        x=y;
    }
}
inline void chkmax(ll &x,ll y)
{
    if(x<y)
    {
        x=y;
    }
}
inline bool Node::operator <(const Node &rhs)const
{
    return this->d[dim]<rhs.d[dim]; 
} 
inline ll newNode()
{
    if(!ptr)
    {
        return ++tot;
    }
    tree[pool[ptr]].clear();
    return pool[ptr--];
}
inline void update(ll x,ll y)
{
    chkmin(tree[x].minn[0],tree[y].minn[0]);
    chkmin(tree[x].minn[1],tree[y].minn[1]);
    chkmax(tree[x].maxn[0],tree[y].maxn[0]);
    chkmax(tree[x].maxn[1],tree[y].maxn[1]);
}
inline void update(ll node)
{
    ll ls=tree[node].ch[0],rs=tree[node].ch[1];
    tree[node].minn[0]=tree[node].maxn[0]=tree[node].nd.d[0];
    tree[node].minn[1]=tree[node].maxn[1]=tree[node].nd.d[1];
    tree[node].size=tree[ls].size+tree[rs].size+1;
    tree[node].sum=tree[ls].sum+tree[rs].sum+tree[node].nd.val;
    if(ls)
    {
        update(node,ls);    
    }       
    if(rs)
    {
        update(node,rs);
    }
}
inline ll create(ll l,ll r,ll d)
{
    ll mid=(l+r)>>1;
    dim=d,nth_element(nd+l,nd+mid,nd+r);
    ll node=newNode();
    tree[node].nd=nd[mid];
    tree[node].ch[0]=l<mid?create(l,mid-1,d^1):0;
    tree[node].ch[1]=r>mid?create(mid+1,r,d^1):0;
    update(node);
    return node;
}
inline void pia(ll node)
{
    if(tree[node].ch[0])
    {
        pia(tree[node].ch[0]);
    }
    nd[++ptr2]=tree[node].nd;
    pool[++ptr]=node;
    if(tree[node].ch[1])
    {
        pia(tree[node].ch[1]);
    }
}
inline void check(ll &node,ll d)
{
    ll ls=tree[node].ch[0],rs=tree[node].ch[1];
    double sz=alpha*tree[node].size;
    if(sz<tree[ls].size||sz<tree[rs].size)
    {
        ptr2=0,pia(node),node=create(1,ptr2,d);
    }
}
inline void insert(Node nd,ll d,ll &node)
{
    if(!node)
    {
        node=newNode(),tree[node].nd=nd,update(node);
        return;
    }
    ll x=tree[node].nd.d[d]<nd.d[d];
    insert(nd,d^1,tree[node].ch[x]);
    update(node),check(node,d);
}
inline ll check(KDTree nd,ll x,ll y,ll xx,ll yy)
{
    ll p=nd.minn[0],q=nd.minn[1],r=nd.maxn[0],s=nd.maxn[1];
    if(x<=p&&xx>=r&&y<=q&&yy>=s)
    {
        return 1;
    }
    if((xx<p||x>r)||(yy<q||y>s))
    {
        return 0;
    }
    return 2;
}
inline ll query(ll x,ll y,ll xx,ll yy,ll node)
{
    ll chk,res=0,p=tree[node].nd.d[0],q=tree[node].nd.d[1];
    ll ls=tree[node].ch[0],rs=tree[node].ch[1];
    if(p>=x&&p<=xx&&q>=y&&q<=yy)
    {
        res+=tree[node].nd.val;
    }
    if(ls)
    {
        chk=check(tree[ls],x,y,xx,yy);
        if(chk==1)
        {
            res+=tree[ls].sum;
        }
        if(chk==2)
        {
            res+=query(ls,x,y,xx,yy);
        }
    }
    if(rs)
    {
        chk=check(tree[rs],x,y,xx,yy);
        if(chk==1)
        {
            res+=tree[rs].sum;
        }
        if(chk==2)
        {
            res+=query(rs,x,y,xx,yy);
        }
    }
    return res;
}
int main()
{
    cnt=read();
    while(1)
    {
        op=read();
        if(op==3)
        {
            return 0;
        }
        if(op==1)
        {
            x=read()^lastAns,y=read()^lastAns,z=read()^lastAns;
            insert((Node){z,x,y},0,rt);
        }
        else
        {
            x=read()^lastAns,y=read()^lastAns;
            xx=read()^lastAns,yy=read()^lastAns;
            printf("%d\n",lastAns=query(x,y,xx,yy,rt));
        }
    }
}

|