More than 2019 cattle off summer school camp (Session 8) D-Distance regularly reconstruction

Topic Portal

Meaning of the questions:

  In a three-dimensional space, given q operations, each operation may add a fixed point in space, or to ask a point, for a query operation, the Manhattan distance from the output point of the nearest fixing point.

Ideas:

  Official Solution: assume that all queries after tagging, then we can find the same once bfs each grid point closest to the point of distance mark, you can ask O (1) answer.

  Now consider periodic incremental markings reconstruction process, referred to add a tag queue, each time the results after pre-bfs out, a new flag in each queue enumeration of violence, these results can take a min.

  When the queue element exceeds a threshold value E, we mark the queue also bfs, updated answer to each location, clear the new mark queue.

  Restraint complexity is O (qnmh / E + qE), when E = nmh take root minimum.

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,b,a) for(int i=b;i>=a;i--)
#define clr(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pii pair<int,int >
using namespace std;
const int maxn=100010;
const int inf=0x3f3f3f3f;
int dis[maxn];
int n,m,h;
int getid(int x,int y,int z){
    return (x-1)*m*h+(y-1)*h+z;
}

int dir[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
struct node{
    int x,y,z;
};
int getdis(node a,node b){
    return abs(a.x-b.x)+abs(a.y-b.y)+abs(a.z-b.z);
}
vector<node >ve;
queue<node >q;
int main(){
    int qi;
    cin>>n>>m>>h>>qi;
    int sq=sqrt(1ll*n*m*h);
    int si=0;
    clr(dis,inf);
    rep(i,1,qi){
        int op,x,y,z;
        scanf("%d%d%d%d",&op,&x,&y,&z);
        if(op==1){
            ve.pb({x,y,z});
            and++;
            if(si==sq){
                rep(i,0,si-1){
                    q.push(ve[i]);
                    dis[getid(ve[i].x,ve[i].y,ve[i].z)]=0;
                }
                while(!q.empty()){
                    node st=q.front();
                    q.pop();
                    rep(i,0,5){
                        int xx=st.x+dir[i][0];
                        int yy=st.y+dir[i][1];
                        int zz=st.z+dir[i][2];
                        if(xx<1||xx>n||yy<1||yy>m||zz<1||zz>h)continue;
                        if(dis[getid(xx,yy,zz)]>dis[getid(st.x,st.y,st.z)]+1){
                            dis[getid(xx,yy,zz)]=dis[getid(st.x,st.y,st.z)]+1;
                            q.push({xx,yy,zz});
                        }
                    }
                }
                ve.clear();
                si=0;
            }
        }else{
            int ans=dis[getid(x,y,z)];
            rep(i,0,si-1){
                ans=min(ans,getdis({x,y,z},ve[i]));
            }
            printf("%d\n",ans);
        }
    }
}

 

Guess you like

Origin www.cnblogs.com/mountaink/p/11334546.html