P8865 NOIP2022 种花 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)。

记 \(a(x, y)\) 代表原文的 \(a_{x, y}\)。

考虑对每个点统计:左上角在该点的 \(\texttt{C-}\),\(\texttt{F-}\) 的数量。最终答案累加每个点对应的答案即可。

那么接下来我们想:对于一个点怎么计算对应的答案?我们生成一个地图来看看:

其中白色代表可以放置花,红色代表不可放置。现在,我们要计算左上角在 \((1, 1)\) 的 \(\texttt{C-}\) 的数量。

较容易看出,\(\texttt{C-}\) 的最上面那一横总共有 \(3\) 种画法,下面是其中一种:

考虑 \(3\) 的意义,其实它是从 \((1, 1)\) 开始,往右最多有几个连续的白色方块(不统计 \((1, 1)\) 本身)。

据此,我们考虑预处理 \(r(x, y)\) 表示 \((x, y)\) 开始向右最多有几个连续的 \(0\)(不统计 \((x, y)\) 本身)。特别地,当 \(a(x, y) = 1\) 时,记 \(r(x, y) = -1\)。

\(r\) 可以通过 \(\Theta(nm)\) 的递推(或者说后缀和)得到,具体来说,当 \(a(x, y) = 1\) 时,\(r(x, y) = -1\),否则 \(r(x, y) = r(x, y + 1) + 1\)。边界是 \(r(x, m +1) = -1\)。

那么 \(\texttt{C-}\) 的剩下一部分(先下再右的整个一个折线)有多少种画法呢?我们发现:

  • 当 \(\texttt{C-}\) 的一竖延伸到 \((3, 1)\) 时,剩下一部分有 \(r(3, 1) = 3\) 种画法;
  • 当 \(\texttt{C-}\) 的一竖延伸到 \((4, 1)\) 时,剩下一部分有 \(r(4, 1) = 0\) 种画法;
  • 当 \(\texttt{C-}\) 的一竖延伸到 \((5, 1)\) 时,剩下一部分有 \(r(5, 1) = 5\) 种画法;
  • 当 \(\texttt{C-}\) 的一竖延伸到 \((6, 1)\) 时,剩下一部分有 \(r(6, 1) = 1\) 种画法。

因此剩下这部分总共有 \(r(3, 1) + r(4, 1) + r(5, 1) + r(6, 1) = 9\) 种画法。根据乘法原理可以得到,以 \((1, 1)\) 为左上角的 \(\texttt{C-}\) 数量有 \(3 \times 9 = 27\) 个。

一般地,\((x, y)\) 对应的 \(\texttt{C-}\) 数量可以表示为 \(r(x, y) \times \sum\limits_{t = x + 2} ^ k r(t, y)\),其中 \(k\) 满足:\(a(x, y) = a(x + 1, y) = \cdots = a(k, y) = 0\),而 \(a(k + 1, y) = 1\),此处我们认为 \(a(n + 1, y) = 1\)。

这里 \(k\) 的存在是考虑 \(\texttt{C-}\) 的那一竖,有时并不能像上面那个例子一样无限向下延伸,如果遇到一个红色方块就需要停止了。比如,若上面的 \((5, 1)\) 是红色,那么 \((1, 1)\) 对应的 \(\texttt{C-}\) 中,除去上面一横的剩下一部分,只剩下 \(r(3, 1) +r(4, 1) = 3\) 种画法。

为了让式子仍然可以 \(\Theta(1)\) 直接计算,我们考虑预处理 \(g(x, y) = \sum \limits _{t=x} ^ k r(t, y)\),\(k\) 的含义和上面相同。递推和 \(r\) 差不多:当 \(a(x, y) = 1\) 时,\(g(x, y) = 0\),否则 \(g(x, y) = g(x + 1, y) +r(x, y)\)。边界是 \(g(n + 1, y) = 0\)。

这样以来,当 \(a(x, y) = 0\) 且 \(a(x + 1, y) = 0\) 时,\((x, y)\) 对应的 \(\texttt{C-}\) 数量就为 \(r(x, y) \times g(x + 2, y)\),否则显然为 \(0\)。请注意检验 \(a(x + 1, y)\) 为 \(0\) 的必要性

接下来计算 \(\texttt{F-}\)。还是上面这个例子,上面那一横的画法显然还是 \(r(1, 1) = 3\)。

剩下一部分因为形状的变化,画法数量也会有变化。当 \(\texttt{F-}\) 的上半竖延伸到 \((3, 1)\) 时,第二个横有 \(r(3, 1) = 3\) 种画法,这个仍然不变。但此时我们还要考虑下半竖,总共还有 \(6 - 3 = 3\) 种画法。因此,当 \(\texttt{F-}\) 的上半竖延伸到 \((3, 1)\) 时,除了第一横的剩下一部分总共有 \(3 \times 3 = 9\) 种画法。而当 \(\texttt{F-}\) 上半竖延伸到 \((5, 1)\) 时,总共有 \(r(5, 1) \times (6 - 5) = 5\) 种。其实也就是在 \(\texttt{C-}\) 的基础上,再套一个乘法原理将下半竖的画法统计进去。

类似一般地,\((x, y)\) 对应的 \(\texttt{F-}\) 数量可以表示为 \(r(x, y) \times \sum \limits _{t = x +2} ^ k r(t, y) \times (k - t)\),其中 \(k\) 满足:\(a(x, y) = a(x + 1, y) = \cdots = a(k, y) = 0\),而 \(a(k + 1, y) = 1\),我们认为 \(a(n + 1, y) = 1\)。

预处理 \(h(x, y) = \sum \limits _{t = x} ^ k r(t, y)\),当 \(a(x, y) = 1\) 时,\(h(x, y) = 0\),否则 \(h(x, y) = h(x +1, y) + r(x, y) \times (k - t)\)。边界是 \(h(n +1, y) = 0\)。

这样以来,当 \(a(x, y) = 0\) 且 \(a(x + 1, y) = 0\) 时,\((x, y)\) 对应的 \(\texttt{F-}\) 数量就为 \(r(x, y) \times h(x + 2, y)\),否则显然为 \(0\)。

时间复杂度 \(\Theta(nm)\)。

/** @Author: crab-in-the-northeast * @Date: 2022-12-01 11:11:02 * @Last Modified by: crab-in-the-northeast* @Last Modified time: 2022-12-01 12:02:12*/
#include <bits/stdc++.h>
#define int long long
inline int read() {int x = 0;bool f = true;char ch = getchar();for (; !isdigit(ch); ch = getchar())if (ch == '-')f = false;for (; isdigit(ch); ch = getchar())x = (x << 1) + (x << 3) + ch - '0';return f ? x : (~(x - 1));
}
inline std :: pair <std :: string, int> rest(bool space = true) {std :: string s;char ch = getchar();for (; !isgraph(ch); ch = getchar());for (; isgraph(ch); ch = getchar())s.push_back(ch);return {space ? " " + s : s, s.length()};
}const int maxn = 1005;
const int maxm = 1005;
const int mod = 998244353;bool a[maxn][maxm];
int r[maxn][maxm], g[maxn][maxm], h[maxn][maxm];signed main() {int T = read(); read();while (T--) {std :: memset(r, -1, sizeof(r));std :: memset(g, 0, sizeof(g));std :: memset(h, 0, sizeof(h));int n = read(), m = read(), C = read(), F = read();for (int i = 1; i <= n; ++i) {std :: string s = rest().first;for (int j = 1; j <= m; ++j)a[i][j] = (s[j] == '1');}for (int i = 1; i <= n; ++i)for (int j = m; j; --j)r[i][j] = a[i][j] ? -1 : (r[i][j + 1] + 1);for (int i = n; i; --i)for (int j = 1; j <= m; ++j)g[i][j] = a[i][j] ? 0 : ((g[i + 1][j] + r[i][j]) % mod);for (int j = 1; j <= m; ++j) {for (int i = n, k = n; i; --i) {if (a[i][j])k = i - 1;elseh[i][j] = (h[i + 1][j] + r[i][j] * (k - i)) % mod;}}int c = 0, f = 0;for (int i = 1; i <= n; ++i) {for (int j = 1; j <= m; ++j) {if (a[i][j] || a[i + 1][j])continue;(c += r[i][j] * g[i + 2][j]) %= mod;(f += r[i][j] * h[i + 2][j]) %= mod;}}printf("%lld %lld\n", c * C, f * F);}return 0;
}

P8865 [NOIP2022] 种花相关推荐

  1. 【题解】P8865 [NOIP2022] 种花(二分答案,前缀和)

    [题解]P8865 [NOIP2022] 种花 场外 VP 选手.唯一场切的一道题,写篇题解纪念一下.( 顺便提一嘴:e 我是真的菜,,其他人&题解这道题都是 \(O(nm)\) 的,就我是 ...

  2. 题解 [NOIP2022] T1 种花

    题解 P8865 [NOIP2022] 种花 Update: \texttt{Update:} Update: 2022.12.04 : 2022.12.04: 2022.12.04: 改进了文章中难 ...

  3. 【每日一算法】种花问题

    微信改版,加星标不迷路! 每日一算法-种花问题 作者:阿广 阅读目录 1 题目 2 解析 1 题目 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会 ...

  4. 捡垃圾、跳大绳、种花、写字,波士顿动力机器狗迎来重大升级

    2021-02-02 12:26:06 机器之心报道 作者:蛋酱.魔王 今天,波士顿动力发布了 Spot 机器人全新视频,除了添加了一条机械臂,它还能实现捡垃圾.跳绳.种花等多种功能. 当你以为波士顿 ...

  5. 校招真题练习011 种花(美团)

    种花 题目描述 公园里有N个花园,初始时每个花园里都没有种花,园丁将花园从1到N编号并计划在编号为i的花园里恰好种A_i朵花,他每天会选择一个区间[L,R](1≤L≤R≤N)并在编号为L到R的花园里各 ...

  6. ML之k-NN:k-NN实现对150朵共三种花的实例的萼片长度、宽,花瓣长、宽数据统计,根据一朵新花的四个特征来预测其种类

    ML之k-NN:k-NN实现对150朵共三种花的实例的萼片长度.宽,花瓣长.宽数据统计,根据一朵新花的四个特征来预测其种类 目录 输出结果 实现代码 输出结果 实现代码 from sklearn im ...

  7. 通俗易懂:贪心算法(三):习题练习 (力扣605种花问题、122买卖股票的最佳时机)

    看完本文,可以顺便解决leetcode以下两个题目: 605.种花问题

  8. JZOJ 4726. 【NOIP2016提高A组模拟8.22】种花

    Description 经过三十多个小时的长途跋涉,小Z和小D终于到了NOI现场--南山南中学.一进校园,小D就被花所吸引了(不要问我为什么),遍和一旁的种花园丁交(J)流(L)了起来. 他发现花的摆 ...

  9. 605. 种花问题003(贪心算法+思路+详解)

    一:题目 假设有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去. 给你一个整数数组 flowerbed 表示花坛,由若干 0 和 1 ...

最新文章

  1. 手把手教你在多种无监督聚类算法实现Python(附代码)
  2. shell字符串截取总结
  3. (转)Cairngorm初学者入门教程 第四节--通过 Model Locator 控制管理 Views
  4. BZOJ 3731: Gty的超级妹子树
  5. 2018,抢票大作战
  6. anki vector robot入门语音指令大全
  7. 通过注册表修改远程桌面默认3389端口
  8. HDU-3065 病毒侵袭持续中 AC自动机又是一板子!
  9. matlab imhist灰度直方图
  10. Nginx学习总结(2)——Nginx手机版和PC电脑版网站配置
  11. 2017-07-22 模拟赛
  12. python能做什么项目-python适合什么开发
  13. Android ADB动态查看内存信息之Watch使用
  14. 随机梯度下降算法(SGD)
  15. 极客学院小程序视频教程
  16. SAP 全线产品大解析!
  17. Base64编解码及其C++实现
  18. FedEx v20.0.7654的CData驱动程序
  19. 联想E480安装MacOS苹果系统记录
  20. 用PHP输出对称菱形的简易办法

热门文章

  1. 网页调用手机自带拨打电话功能
  2. 第二十四讲项目3-一元二次方程全解
  3. 查看当前jdk所支持的jvm参数
  4. python篮球-资深程序员教你,利用python预测NBA比赛结果,太精彩了
  5. C++描述 LeetCode 26. 删除排序数组中的重复项
  6. Y22M12D05_1687_从仓库到码头运输箱子
  7. Spring 面试63问
  8. Delphi 文件处理(4)
  9. 解决:ValueError: (‘Unrecognized keyword arguments:‘, dict_keys([‘ragged‘]))
  10. 巧用“沃通国际认证”防钓鱼