hdu5126 stars

题目描述

题解:

和二维的比起来差不多。

但是这是四维偏序。

所以搞一下CDQ套CDQ。

CDQ是维度a已经有序,按维度b排序,然后将维度c存入一维数据结构。

所以我们在第一层CDQ中分治处理,将合法的前一半打标记。

然后进入第二层CDQ,处理打标记的点对没打标记的点的影响。

可以说是将两维压成一维。

想法仍然是容斥。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 50050
#define ll long long
inline int rd()
{
    int f=1,c=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
    return f*c;
}
struct node
{
    int x,y,z,t,w,k,id;
    int typ;
    node(){}
    node(int x,int y,int t,int w,int k,int i):x(x),y(y),t(t),w(w),k(k),id(i){}
}p[N<<3],tmp[N<<3],sec[N<<3];
bool cmpx(node a,node b)
{
    return a.x<b.x;
}
bool cmpid(node a,node b)
{
    return a.id<b.id;
}
int cnt;
struct PR
{
    int x,id;
    PR(){}
    PR(int x,int i):x(x),id(i){}
}Z[N<<3];
bool cmp(PR a,PR b)
{
    return a.x<b.x;
}
int T,Q,typ,tim;
int kkk[N<<1],ct;
ll ans[N];
struct BIT
{
    ll v[N<<3];
    void up(int x,ll d)
    {
        if(!x)return ;
        while(x<(N<<3))
            v[x]+=d,x+=(x&-x);
    }
    ll down(int x)
    {
        if(!x)return 0;
        ll ret = 0ll;
        while(x)
            ret+=v[x],x-=(x&-x);
        return ret;
    }
}tr;
void init()
{
    cnt=ct=0;
    tim=1;
}
void ap(int x,int y,int z,int t,int w,int k)
{
    cnt++;
    p[cnt] = node(x,y,t,w,k,cnt);
    Z[cnt] = PR(z,cnt);
}
void Sort(int l,int r)
{
    int mid = (l+r)>>1;
    int i=l,j=mid+1,k=l;
    while(i<=mid&&j<=r)
    {
        while(i<=mid&&tmp[i].y<=tmp[j].y)
        {
            sec[k]=tmp[i];
            i++,k++;
        }
        while(j<=r&&tmp[i].y>tmp[j].y)
        {
            sec[k]=tmp[j];
            j++,k++;
        }
    }
    while(i<=mid)
    {
        sec[k]=tmp[i];
        i++,k++;
    }
    while(j<=r)
    {
        sec[k]=tmp[j];
        j++,k++;
    }
    for(i=l;i<=r;i++)
        tmp[i]=sec[i];
}
void cdq2(int l,int r)
{
    if(l==r)return ;
    int mid = (l+r)>>1;
    cdq2(l,mid);cdq2(mid+1,r);
    Sort(l,mid);Sort(mid+1,r);
    int i,j;
    for(i=l,j=mid+1;j<=r;j++)
    {
        while(i<=mid&&tmp[i].y<=tmp[j].y)
        {
            if(tmp[i].typ&&tmp[i].w)tr.up(tmp[i].z,tmp[i].w);
            i++;
        }
        if(kkk[tmp[j].t]&&!tmp[j].typ)ans[kkk[tmp[j].t]]+=1ll*tmp[j].k*tr.down(tmp[j].z);
    }
    for(i=i-1;i>=l;i--)
        if(tmp[i].typ&&tmp[i].w)tr.up(tmp[i].z,-tmp[i].w);
}
void cdq1(int l,int r)
{
    if(l==r)return ;
    int mid = (l+r)>>1;
    cdq1(l,mid),cdq1(mid+1,r);
    sort(p+l,p+mid+1,cmpx);
    sort(p+mid+1,p+r+1,cmpx);
    int i=l,j=mid+1,k=l;
    while(i<=mid&&j<=r)
    {
        while(i<=mid&&p[i].x<=p[j].x)
        {
            tmp[k]=p[i],tmp[k].typ=1;
            i++,k++;
        }
        while(j<=r&&p[i].x>p[j].x)
        {
            tmp[k]=p[j],tmp[k].typ=0;
            j++,k++;
        }
    }
    while(i<=mid)
    {
        tmp[k]=p[i],tmp[k].typ=1;
        i++,k++;
    }
    while(j<=r)
    {
        tmp[k]=p[j],tmp[k].typ=0;
        j++,k++;
    }
    cdq2(l,r);
}
int main()
{
    T=rd();
    while(T--)
    {
        init();
        Q = rd();
        for(int ax,ay,az,bx,by,bz,i=1;i<=Q;i++)
        {
            typ=rd();
            if(typ==1)
            {
                ax=rd(),ay=rd(),az=rd();
                ap(ax,ay,az,tim,1,0);
            }else
            {
                ax=rd(),ay=rd(),az=rd(),bx=rd(),by=rd(),bz=rd();
                tim++,ct++;
                kkk[tim]=ct;
                ax--,ay--,az--;
                ap(ax,ay,az,tim,0,-1);
                ap(ax,ay,bz,tim,0,1);
                ap(ax,by,az,tim,0,1);
                ap(ax,by,bz,tim,0,-1);
                ap(bx,ay,az,tim,0,1);
                ap(bx,ay,bz,tim,0,-1);
                ap(bx,by,az,tim,0,-1);
                ap(bx,by,bz,tim,0,1);
                tim++;
            }
        }
        sort(Z+1,Z+1+cnt,cmp);
        for(int las=-1,k=0,i=1;i<=cnt;i++)
        {
            if(las!=Z[i].x)
            {
                las = Z[i].x;
                k++;
            }
            p[Z[i].id].z = k;
        }
        cdq1(1,cnt);
        for(int i=1;i<=ct;i++)
            printf("%I64d\n",ans[i]);
        for(int i=1;i<=ct;i++)
            ans[i]=0;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/LiGuanlin1124/p/10143528.html