提示1
如果 NNN 和 MMM 的范围为 [3,1000][3, 1000][3,1000] 如何解决这个问题?
提示2
每个遗迹的坐标具体是多少真的很重要吗?
题目解析
如果 NNN 和 MMM 比较小的话,我们可以使用「二维数组」存储地图信息,把所有遗迹在「二维数组」中标注出来,然后在地图上做 DFS/BFS\tt{DFS/BFS}DFS/BFS 求「连通块」的数量即可。
但是现在 NNN 和 MMM 很大,我们完整无法去存储整个地图及遗迹的细节。
但是遗迹的坐标具体是多少,真的很重要吗?
不妨设想,这是一个可以放缩的地图。
那么可以发现,对地图放大或者缩小并不会影响其被分成几个部分的结果。
那么其实我们真正需要记录的只是遗迹之间的相对关系。
前后没有遗迹的行和列,并不需要被记录下来,不会影响答案。
所以我们可以使用「坐标离散化」的技巧:
对于每个遗迹我们只需要存储遗迹的坐标以及其前后的行和列就足够了,即:
Ai−1,Ai,Ai+1 (1≤Ai−1<Ai+1≤N)\tt{A_i - 1, A_i, A_i + 1\ (1 \le A_i - 1 < A_i + 1 \le N)}Ai −1,Ai ,Ai +1 (1≤Ai −1<Ai +1≤N),
Bi−1,Bi,Bi+1 (1≤Bi−1<Bi+1≤M)\tt{B_i - 1, B_i, B_i + 1\ (1 \le B_i - 1 < B_i + 1 \le M)}Bi −1,Bi ,Bi +1 (1≤Bi −1<Bi +1≤M),
Ci−1,Ci,Ci+1 (1≤Ci−1<Ci+1≤N)\tt{C_i - 1, C_i, C_i + 1\ (1 \le C_i - 1 < C_i + 1 \le N)}Ci −1,Ci ,Ci +1 (1≤Ci −1<Ci +1≤N),
Di−1,Di,Di+1 (1≤Di−1<Di+1≤M)\tt{D_i - 1, D_i, D_i + 1\ (1 \le D_i - 1 < D_i + 1 \le M)}Di −1,Di ,Di +1 (1≤Di −1<Di +1≤M)。
这样地图上最多存储 6K×6K\tt{6K \times 6K}6K×6K 的信息对于本题 1≤K≤5001 \le K \le 5001≤K≤500 完全可以使用「二维数组」存储离散化后的地图。
然后将遗迹及其前后的 XXX 坐标和 YYY 坐标分别做离散化处理,保留他们的相对关系。
完成「坐标离散化」后,我们使用离散化后的遗迹对离散化后的地图进行标记,并在离散化后的地图上做 DFS/BFS\tt{DFS/BFS}DFS/BFS 求「连通块」的数量即可。
AC代码
复杂度分析
坐标离散化的时间复杂度为 O(6Klog6K)\mathrm{O}(6K \log{6K})O(6Klog6K);
离散化后在地图上标注遗迹的复杂度为 O(6K2)\mathrm{O}(6K^2)O(6K2);
在离散化后的地图上做 DFS/BFS\tt{DFS/BFS}DFS/BFS 求「连通块」的数量复杂度为 O(36K2)\mathrm{O}(36K^2)O(36K2);
总的时间复杂度为 O(36K2)\mathrm{O}(36K^2)O(36K2)。