2019牛客多校第八场D Distance(重构思维)题解
题意:
传送门
三维长方体有\(n*m*h <=1e5\),现给定\(q<=1e5\)个询问,每次询问给出:
\(1\ x\ y\ z\)表示把\(x\ y\ z\)标记一下
\(2\ x\ y\ z\)询问\(x\ y\ z\)和已经标记的点的最近曼哈顿距离是多少
思路:
我们可以花\(O(nmh)\)的时间预处理出所有点到已标记点的最小距离,也可以花\(O(L)\)的时间处理出某点到\(L\)个点的最小距离,那么中和一下,我们用一个栈表示还未预处理的点,一旦栈超过\(L\)那就拿去预处理,答案为预处理出的最小值和遍历栈中最小值的最小值。时间复杂度\(O(nmhq/L+qL)\),当\(L = \sqrt{nmh}\)时取到最小值。
代码:
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 5;
const int INF = 0x3f3f3f3f;
const ull seed = 131;
const ll MOD = 1e9;
using namespace std;
int n, m, h, q, e;
int dis[maxn * 2];
int getid(int x, int y, int z){
return n * m * (z - 1) + m * (x - 1) + y;
}
struct Node{
int x, y, z;
int step;
};
vector<Node> s;
int to[6][3] = {{0, 0, 1}, {0, 0, -1}, {1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}};
void bfs(){
queue<Node> q;
while(!q.empty()) q.pop();
Node a, b;
for(int i = 0; i < s.size(); i++){
a.x = s[i].x, a.y = s[i].y, a.z = s[i].z, a.step = 0;
dis[getid(a.x, a.y, a.z)] = 0;
q.push(a);
}
s.clear();
while(!q.empty()){
a = q.front();
q.pop();
for(int i = 0; i < 6; i++){
b.x = a.x + to[i][0];
b.y = a.y + to[i][1];
b.z = a.z + to[i][2];
b.step = a.step + 1;
if(b.x < 1 || b.y < 1 || b.z < 1 || b.x > n || b.y > m || b.z > h) continue;
if(dis[getid(b.x, b.y, b.z)] <= b.step) continue; //!!!
dis[getid(b.x, b.y, b.z)] = b.step;
q.push(b);
}
}
}
int getdis(int x, int y, int z, const Node c){
return abs(x - c.x) + abs(y - c.y) + abs(z - c.z);
}
int main(){
scanf("%d%d%d%d", &n, &m, &h, &q);
e = sqrt(n * m * h);
s.clear();
memset(dis, INF, sizeof(dis));
while(q--){
int o, x, y, z;
scanf("%d%d%d%d", &o, &x, &y, &z);
if(o == 1){
s.push_back(Node{x, y, z, 0});
if(s.size() >= e) bfs();
}
else{
int ans = dis[getid(x, y, z)];
for(int i = 0; i < s.size(); i++){
ans = min(ans, getdis(x, y, z, s[i]));
}
printf("%d\n", ans);
}
}
return 0;
}

浙公网安备 33010602011771号