2019牛客暑期多校训练营(第八场)D Distance —— 三维树状数组求空间中与某个点最近的点的曼哈顿距离

This way

题意:

两种操作:
1 x,y,h表示在x,y,h位置添加一个点
2 x,y,h表示询问与这个位置最近的点的曼哈顿距离是多少

题解:

cf上有一道很像的题目,那个是问三维空间中最远的两个点的距离,用8个线段树维护,这道题线段树我空间开不下,所以用树状数组。3个符号,总共有8种情况。但是值会有负数,所以x需要+n+1,y+m+1,z+h+1。
哈希值表示空间中每个点在一维上独立存在的值,因为y+m+1可能会=2m+1,所以需要乘上2m+2
那么我们为什么查询的是每一个点的x,y,z比他小的情况呢?
因为对于8种情况中的这种情况,我们是考虑了查询的点的三维的值-被查询的点的三维的值是非负数的情况,比如x1=1和x2=3的时候,我们一定查的是-x1与-x2的情况,因为这样才是减去之后的绝对值

#include
using namespace std;
const int N=2e6+5;
int n,m,h;
int get_hash(int x,int y,int z){return x*(2*m+2)*(2*h+2)+y*(2*h+2)+z;}
struct node
{
    int mx[N];
    int lowbit(int x){return x&(-x);}
    void update(int x,int y,int z,int v)
    {
        for(int i=x;i<=n*2+5;i+=lowbit(i))
            for(int j=y;j<=m*2+5;j+=lowbit(j))
                for(int k=z;k<=h*2+5;k+=lowbit(k))
                    mx[get_hash(i,j,k)]=max(mx[get_hash(i,j,k)],v);
    }

    int query(int x,int y,int z)
    {
        int ans=-1e9;
        for(int i=x;i;i-=lowbit(i))
            for(int j=y;j;j-=lowbit(j))
                for(int k=z;k;k-=lowbit(k))
                    ans=max(ans,mx[get_hash(i,j,k)]);
        return ans;
    }
}tr[8];
int xmov[]={1,1,1,1,-1,-1,-1,-1};
int ymov[]={1,1,-1,-1,1,1,-1,-1};
int zmov[]={1,-1,1,-1,1,-1,1,-1};
int main()
{
    for(int i=0;i<8;i++)
        for(int j=0;j

你可能感兴趣的:(树状数组)