「USACO 2021.1 Platinum」Paint by Letters
「USACO 2021.1 Platinum」Paint by Letters
统计连通块问题,暴力是 \(O(qn^2)\) ,而且常数大
容易想到 平面图的欧拉定理 优化
下文和代码中, \(V,E,F\) 分别为点集,边集,区域集合
其中 \(|V|\) 可以直接得到, \(|E|\) 可以 \(O(n^2)\) 前缀和预处理出来, \(O(1)\) 查询
下面处理区域个数
Solution1
前缀和所有大小为1(即被四个点包住的)区域,暴力预处理所有大小 \(>1\) 的区域,个数为 \(O(\frac{nm}{4})\)
然后可以转化为一个对于给定矩形查询包含的 矩形个数 的问题
实际上这个题目 \(q\) 小直接枚举就是了。。
复杂度为 \(O(nm+q\frac{nm}{4})\) ,足够通过时限
写的够丑可以得到这个代码
矩形区间查询问题 ,不知道有没有什么更好的方法
ps:垃圾数据没有卡,因此实际上数据中的空白块数量非常少,预处理写得稍微好一点可能还比下面的做法常数小
\[ \ \]
Solution2
用 \((x,y)\) 表示 \((x,y),(x+1,y),(x,y+1),(x+1,y+1)\) 中间的一个空白区域
这些空白块会被染色块之间的边隔开,但是依然可以形成四联通块
预处理出所有空白区域的连通块,每个连通块选取一个代表点 \(S_i\)
我们要统计一个区域中的空白连通块个数,注意到
跨出区域范围的空白点,并不是断开了,而是和最外层的无穷空白区合并在一起
因此可以先求出在区域中存在的连通块个数,然后将连通到区域外的部分去掉
具体实现上:
前缀和预处理出 \(S_i\) 的位置,每次查询区域中的 \(S_i\) 个数(这样的统计不完全)
然后将 \(S_i\) 在区域中,且跨出区域的白色连通块删掉即可
跨出部分枚举四条边界即可
每次查询枚举边界,因此复杂度为 \(O(nm+q(n+m))\)
1 |
|