HDU5126
Description
\(T\) 组数据,给一个空的三维空间,\(Q\) 次操作,分为插入一个点和查询某个立方体内点的个数。
\(T \le 10,Q \le 5 \times 10^4\)
Sol
题目没说强制在线那先离线下来再说。
然后可以娴熟的把询问操作用差分变成八个子问题。
然后就会发现这是个偏序问题,每一个点有四个属性(三维坐标,插入时间)。对于一个询问,对它的答案有贡献的点是三维坐标均小于它本身且比它早插入的点。
于是四维偏序套三层CDQ分治就好了。当然两层CDQ加树状数组也行但是要注意离散化。
时间复杂度 \(\mathrm{O}(n \log^3 n)\)。
调了两天,累死咯。
Hint
- 数组开八倍。
- 多测不清空,爆零两行泪。
Code
#include<cstdio>
#include<algorithm>
#include<cstring>
using std::sort;
const int M=5e4+5;
inline int read(){int x(0),op(0);char ch=getchar();while(ch<'0'||ch>'9')op|=(ch==45),ch=getchar();while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return op?-x:x;}
inline int ssread(){int x;scanf("%d",&x);return x;}
#ifndef ONLINE_JUDGE
#define read ssread
#endif
struct node{
int a,b,c,d,t;
}a[M<<3],b[M<<3],c[M<<3],tmp[M<<3];
bool cmpa(node x,node y){return x.a!=y.a?x.a<y.a:x.t<y.t;}
bool cmpb(node x,node y){return x.b!=y.b?x.b<y.b:x.t<y.t;}
bool cmpc(node x,node y){return x.c!=y.c?x.c<y.c:x.t<y.t;}
int Ans[M<<4],n,m,qt;
void solve3(int l,int r){
if(l>=r)return;
int mid=l+r>>1;
solve3(l,mid);solve3(mid+1,r);
int i=l,p=l;
for(int j=mid+1,cnt=0;j<=r;){
while(i<=mid&&c[i].d<=c[j].d){
if(!c[i].t)cnt++;
tmp[p++]=c[i++];
}
if(c[j].t)Ans[c[j].t]+=cnt;
tmp[p++]=c[j++];
}
while(i<=mid)tmp[p++]=c[i++];
for(i=l;i<=r;++i)c[i]=tmp[i];
}
void solve2(int l,int r){
if(l>=r)return;
int mid=l+r>>1,n=0;
solve2(l,mid);solve2(mid+1,r);
for(int i=l;i<=mid;++i)if(!b[i].t)c[++n]=b[i];
for(int i=mid+1;i<=r;++i)if(b[i].t)c[++n]=b[i];
sort(c+1,c+n+1,cmpc);
solve3(1,n);
}
void solve1(int l,int r){
if(l>=r)return;
int mid=l+r>>1,n=0;
solve1(l,mid);solve1(mid+1,r);
for(int i=l;i<=mid;++i)if(!a[i].t)b[++n]=a[i];
for(int i=mid+1;i<=r;++i)if(a[i].t)b[++n]=a[i];
sort(b+1,b+n+1,cmpb);
solve2(1,n);
}
void addp(int x,int y,int z,int w,int t){
a[++n]=(node){x,y,z,w,t};
}
void work(){
m=read();n=0;qt=0;
memset(Ans,0,sizeof(Ans));
for(int i=1,x[2],y[2],z[2];i<=m;++i){
int op=read();x[1]=read(),y[1]=read(),z[1]=read();
if(op==1)addp(x[1],y[1],z[1],i,0);
else{
qt++;
x[0]=read(),y[0]=read(),z[0]=read();
x[1]--;y[1]--;z[1]--;
for(int k=0;k<8;++k)addp(x[bool(k&1)],y[bool(k&2)],z[bool(k&4)],i,qt+M*k);
}
}
sort(a+1,a+n+1,cmpa);
solve1(1,n);
for(int i=1;i<=qt;++i){
int ans=0;
for(int j=0;j<8;++j)ans+=(__builtin_popcount(j)&1?-1:1)*Ans[j*M+i];
printf("%d\n",ans);
}
}
int main(){
int T=read();
while(T--)work();
return 0;
}
标签:ch,return,int,题解,mid,HDU5126,stars,include
From: https://www.cnblogs.com/pokefunc/p/17099750.html