Distance
链接:https://ac.nowcoder.com/acm/contest/888/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
Gromah and LZR have entered the fourth level. There is a blank cube with size n×m×hn\times m\times hn×m×h hanging on the wall.
Gromah soon finds a list beside the cube, there are qq_{}q instructions in the list and each instruction is in one of the following two formats:
2. (2,x,y,z)(2,x, y, z)_{}(2,x,y,z), meaning to determine the minimum Manhattan Distance to the given position (x,y,z)(x, y, z)_{}(x,y,z) among all tagged positions
Manhattan Distance between two positions (x1,y1,z1),(x2,y2,z2)(x_1, y_1, z_1), (x_2, y_2, z_2)(x1,y1,z1),(x2,y2,z2) is defined as ∣x1−x2∣+∣y1−y2∣+∣z1−z2∣|x_1 - x_2| + |y_1 - y_2| + |z_1 - z_2|∣x1−x2∣+∣y1−y2∣+∣z1−z2∣.
LZR also finds a note board saying that the password of this level is the sequence made up of all results of the instructions in format 2.
输入描述:
The first line contains four positive integers n,m,h,qn,m,h,q_{}n,m,h,q, denoting the sizes in three dimensions of the cube and the number of instructions.
Following qq_{}q lines each contains four positive integers op,x,y,zop,x, y, z_{}op,x,y,z, where op=1op=1_{}op=1 means to add a tag on (x,y,z)(x,y,z)_{}(x,y,z) while op=2op=2_{}op=2 means to make a query on (x,y,z)(x,y,z)_{}(x,y,z).
1≤n×m×h,q≤105,1≤x≤n,1≤y≤m,1≤z≤h1 \le n\times m\times h, q\le 10^5, 1 \le x \le n, 1 \le y \le m, 1 \le z \le h1≤n×m×h,q≤105,1≤x≤n,1≤y≤m,1≤z≤h
It is guaranteed that the first instruction is in format 1 and that no position will be tagged more than once.
输出描述:
For each instruction in format 2, output the answer in one line.
示例1
说明
For the first query, there is only one tagged position (1,1,1)(1,1,1)_{}(1,1,1) currently, so the answer is ∣1−2∣+∣1−3∣+∣1−3∣=5|1-2| + |1-3| + |1-3| = 5_{}∣1−2∣+∣1−3∣+∣1−3∣=5.
For the second query, (3,1,1)(3,1,1)_{}(3,1,1) is the nearest tagged position, so the answer is ∣3−3∣+∣1−3∣+∣1−2∣=3|3-3| + |1-3| + |1-2| = 3_{}∣3−3∣+∣1−3∣+∣1−2∣=3.
思路:定期重构。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e5+10; const ll mod=1e9+7; const double eps=1e-7; int n,m,h,q,dp[maxn]; struct node{ int x,y,z; }; vector<node>e; vector<int>ex,ey,ez; int dx[6]={1,-1,0,0,0,0}; int dy[6]={0,0,1,-1,0,0}; int dz[6]={0,0,0,0,1,-1}; int getid(int x,int y,int z){ return x*m*h+y*h+z; } queue<node>que; void update(){ while(!que.empty())que.pop(); for(register int i=0;i<ex.size();++i){ dp[getid(ex[i],ey[i],ez[i])]=0; que.push(node{ex[i],ey[i],ez[i]}); } while(!que.empty()){ node cur=que.front(); que.pop(); for(register int i=0;i<6;++i){ int nx=cur.x+dx[i]; int ny=cur.y+dy[i]; int nz=cur.z+dz[i]; if(nx<1||ny<1||nz<1||nx>n||ny>m||nz>h)continue; if(dp[getid(nx,ny,nz)]>dp[getid(cur.x,cur.y,cur.z)]+1){ dp[getid(nx,ny,nz)]=dp[getid(cur.x,cur.y,cur.z)]+1; que.push(node{nx,ny,nz}); } } } ex.clear(); ey.clear(); ez.clear(); } int query(int x,int y,int z){ int ans=dp[getid(x,y,z)]; for(int i=0;i<ex.size();++i){ ans=min(ans,abs(x-ex[i])+abs(y-ey[i])+abs(z-ez[i])); } return ans; } int main() { //freopen("1.txt","r",stdin); scanf("%d%d%d%d",&n,&m,&h,&q); memset(dp,0x3f3f3f3f,sizeof(dp)); int op,x,y,z; while(q--){ scanf("%d%d%d%d",&op,&x,&y,&z); if(op==1){ ex.emplace_back(x); ey.emplace_back(y); ez.emplace_back(z); } else{ printf("%d\n",query(x,y,z)); } if(ex.size()==1000){ update(); } } return 0; }