[正睿集训2021] Grid with mirrors

这么好的题到底哪里来的啊,我在网上找怎么都找不到。

一、题目

题目描述

给你 \(n\times n\) 的矩阵,其中有 \(m\) 个障碍物,每次可以选择从当前方向走或者是转向 \(90\) 度,定义 \(f(x,y)\) 为从 \((1,1)\)\((x,y)\) 的最小转向次数,\(\tt zxy\) 想要知道对于不是障碍物的 \((x,y)\)\(\sum f(x,y)\) 是多少呢?

数据范围

\(1\leq n\leq 10^5,0\leq m\leq 10^5\)

二、解法

暴力跑是 \(O(n^2)\) 的,你会发现根本就没有办法优化。

感觉很多这种迷宫题最后都要 转化到图论方向去 ,我们尝试构造本题的图论模型。我们不可能暴力建出 \(O(n^2)\) 个点,仔细想一想 转向 这个东西怎么体现在我们图论的 上。也就是我们取出每一个极长的行和列(这是依照障碍物划分的),他的内部是可以随便走的所以我们把很多个点压成了一个点。边就是行和列之间的连边,代表了一次转向,而且边权一定是 \(1\)

这个图的性质有两点:边权为 \(1\) \(/\) 它是一个二分图。我们先来解决计算答案的问题吧,设 \(dis[i]\) 表示图上起点到 \(i\) 的距离,那么 \(f(x,y)=\min(dis[idx],dis[idy])\)\(idx\)\(idy\) 分别表示这个点所在的极长行或者极长列。

这个 \(\min\) 有点恶心啊,但是结合二分图的性质,发现 \(dis[idx]\)\(dis[idy]\) 相差一定为 \(1\)(因为起点只有一个),那么 \(f(x,y)=(dis[idx]+dis[idy]-1)/2\),转化成了一个求和的柿子,现在我们只需要算出 \(dis\) 数组。

边数是 \(O(n^2)\) 的,这道题的连边方式可以用类似 线段树优化建图 的方式来做。这时候奇技淫巧来了(就讲行连列吧):我们先做一遍扫描线,维护出一棵表示现有的极长列的线段树,把每一个极长行向线段树上的 \([l,r]\) 连边。但由于以前的连边结果也是要保存的 ,所以我们把线段树换成主席树进行上面的过程。

对于这种方法,我想称之为 主席树优化建图

//没有提交的地方,所以我没写代码。
//但是思路还是很有启发性的哦 ^_^
posted @ 2021-01-02 10:23  C202044zxy  阅读(74)  评论(0编辑  收藏  举报