\(\text{Solution}\)

这还是 [Lydsy2017省队十连测] 的题

不得不说 \(FFT\) 在字符串匹配中的妙啊!

前面做了道一维的题,现在这是二维的

从题目入手,不考虑可不可达

如果舰队从天而降,考虑其可以落到以那些点为左上角的点

先将地图压成一维,一行接着一行,礁石处为 \(1\) 其余为 \(0\)

抽出包含舰队的最小矩形,按照原来地图行长,从矩阵开头到结尾压成一维,舰队处为 \(1\),其余为 \(0\)

构造匹配函数 \(F_i\) 表示大矩形以 \(i\) 为左上角能否匹配,\(F_i =\sum_j A_{i+j}\cdot B_j\)

则 \(F_i = 0\) 是可行,将 \(A\) 翻转,\(F_i=\sum_j A_{n\cdot m-1-i-j}\cdot B_j\)

这是一个多项式卷积形式,\(NTT\) 即可

于是我们得到了若干个可放入舰队的左上角

我们还要知道那些左上角可达,从小矩阵左上角开始 \(BFS\) 即可

然而我们仍需要那些空地可以被舰队掠过

考虑将可达左上角即为 \(1\),其余为 \(0\),\(B\) 中舰队为 \(1\)

那么 \(i\) 位置可达,需要存在一个可达左上角 \(i-j\)

考虑构造函数 \(F_i = \sum_j A_{i-j} \cdot B_{j}\)

当 \(F_i > 0\) 则该位置可达

发现仍是多项式卷积形式,继续 \(NTT\) 即可

\(\text{Code}\)

#include <cstdio>
#include <iostream>
#define RE register
#define IN inline
using namespace std;
typedef long long LL; const int N = 705, P = 998244353, g = 3;
char str[N][N];
int n, m, vis[N][N], x0 = N, y0 = N, x1 = 0, y1 = 0, rev[N * N * 2];
int fx[4][2] = {{0, -1}, {-1, 0}, {1, 0}, {0, 1}};
LL a[N * N * 2], b[N * N * 2];
struct Point{int x, y;}Q[N * N]; IN int Get(int x, int y){return (x - 1) * m + y - 1;}
IN int get(int x, int y){return (x - x0) * m + y - y0;}
IN int fpow(LL x, int y){LL s = 1; for(; y; y >>= 1, x = x * x % P) if (y & 1) s = s * x % P; return s;}
IN void NTT(LL *a, int n, int inv)
{
if (n == 1) return;
for(RE int i = 0; i < n; i++) if (i < rev[i]) swap(a[i], a[rev[i]]);
for(RE int mid = 1; mid < n; mid <<= 1)
{
int I = fpow(g, (P - 1) / (mid << 1));
if (inv == -1) I = fpow(I, P - 2);
for(RE int i = 0; i < n; i += (mid << 1))
{
LL W = 1;
for(RE int j = 0, x, y; j < mid; j++, W = W * I % P)
x = a[i + j], y = W * a[i + j + mid] % P,
a[i + j] = (x + y) % P, a[i + j + mid] = (x - y + P) % P;
}
}
}
void BFS()
{
int head = 0, tail = 1; Q[1] = Point{x0, y0}, vis[x0][y0] = 0;
while (head < tail)
{
Point z = Q[++head]; a[Get(z.x, z.y)] = 1;
for(RE int k = 0; k < 4; k++)
{
int x = z.x + fx[k][0], y = z.y + fx[k][1];
if (x > 0 && x <= n && y > 0 && y <= m && vis[x][y]) vis[x][y] = 0, Q[++tail] = Point{x, y};
}
}
} int main()
{
freopen("sailing.in", "r", stdin), freopen("sailing.out", "w", stdout);
scanf("%d%d", &n, &m);
for(RE int i = 1; i <= n; i++) scanf("%s", str[i] + 1);
for(RE int i = 1; i <= n; i++)
for(RE int j = 1; j <= m; j++)
if (str[i][j] == 'o') x0 = min(x0, i), y0 = min(y0, j), x1 = max(x1, i), y1 = max(y1, j);
else if (str[i][j] == '#') a[n * m - 1 - Get(i, j)] = 1;
for(RE int i = 1; i <= n; i++)
for(RE int j = 1; j <= m; j++) if (str[i][j] == 'o') b[get(i, j)] = 1; int lim = 1; while (lim < n * m) lim <<= 1; int inv = fpow(lim, P - 2);
int bit = 0; while ((1 << bit) < lim) bit++;
for(RE int i = 0; i < lim; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1)); NTT(a, lim, 1), NTT(b, lim, 1);
for(RE int i = 0; i < lim; i++) a[i] = a[i] * b[i] % P;
NTT(a, lim, -1); for(RE int i = 0; i < lim; i++) a[i] = a[i] * inv % P; for(RE int i = 1; i <= n + x0 - x1; i++)
for(RE int j = 1; j <= m + y0 - y1; j++)
if (!a[n * m - 1 - Get(i, j)]) vis[i][j] = 1; for(RE int i = 0; i < lim; i++) a[i] = 0;
BFS(), NTT(a, lim, 1);
for(RE int i = 0; i < lim; i++) a[i] = a[i] * b[i] % P;
NTT(a, lim, -1); for(RE int i = 0; i < lim; i++) a[i] = a[i] * inv % P; int ans = 0;
for(RE int i = 0; i < n * m; i++) if (a[i] > 0) ans++;
printf("%d\n", ans);
}

JZOJ 5062. 【GDOI2017第二轮模拟day1】航海舰队的更多相关文章

  1. GDOI2017第二轮模拟day1 总结

    平民比赛 这场比赛的暴力分非常友好. 但是我并没有拿到全部的暴力分. 1(暴力分\(60/100\)) 暂时我可以拿的暴力分为\(30/100\),直接mst模拟即可. 然而当时打了个辣鸡莫队,结果爆 ...

  2. 【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树

    题面 在Byteland一共有n 个城市,编号依次为1 到n,它们之间计划修建m条双向道路,其中修建第i 条道路的费用为ci. Byteasar作为Byteland 公路建设项目的总工程师,他决定选定 ...

  3. [jzoj5073 GDOI2017第二轮模拟] 影魔

    Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵 ...

  4. 【JZOJ5064】【GDOI2017第二轮模拟day2】友好城市 Kosarajo算法+bitset+ST表+分块

    题面 在Byteland 一共有n 座城市,编号依次为1 到n,这些城市之间通过m 条单向公路连接. 对于两座不同的城市a 和b,如果a 能通过这些单向道路直接或间接到达b,且b 也能如此到达a,那么 ...

  5. 【JZOJ5086】【GDOI2017第四轮模拟day1】数列 折半搜索

    题面 有一个长度为n 的排列,现在有一些位置的数已经模糊不清了,你只知道这个排列的逆序对个数是K,你能计算出总共有多少可能的排列吗? 对于100% 的数据,n <=10^3,K<=10^9 ...

  6. 【JZOJ5071】【GDSOI2017第二轮模拟】奶酪 树形dp

    题面 CJY很喜欢吃奶酪,于是YJC弄到了一些奶酪,现在YJC决定和CJY分享奶酪. YJC弄到了n-1块奶酪,于是他把奶酪挂在了一棵n个结点的树上,每根树枝上挂一块奶酪,每块奶酪都有重量. YJC和 ...

  7. 【JZOJ5068】【GDSOI2017第二轮模拟】树 动态规划+prufer序列

    题面 有n个点,它们从1到n进行标号,第i个点的限制为度数不能超过A[i]. 现在对于每个s (1 <= s <= n),问从这n个点中选出一些点组成大小为s的有标号无根树的方案数. 10 ...

  8. DFRobot万物互联大赛第二轮

    前言 最近放在阳台的花草被啥东西给吃了,然后厨房挂在墙上的小虾米也不知道咋的被抓破吃光了(我怀疑是隔隔壁两条泰迪),所以打算做个简单的项目,教训一下偷吃贼.时间比较仓促,内容比较多,能力有比较有限,好 ...

  9. LOJ 6060「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set(线性基,贪心)

    LOJ 6060「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set $ solution: $ 这一题的重点在于优先级问题,我们应该先保证总和最大,然后再保证某一个最小.于是我 ...

  10. 【百度之星2014~初赛(第二轮)解题报告】Chess

    声明 笔者近期意外的发现 笔者的个人站点http://tiankonguse.com/ 的非常多文章被其他站点转载.可是转载时未声明文章来源或參考自 http://tiankonguse.com/ 站 ...

随机推荐

  1. SpringBoot2.5.1+Mybatis-Plus3.4.3:(Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required)

    项目引发这个问题: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required <parent> <group ...

  2. [论文阅读] 颜色迁移-N维pdf迁移

    [论文阅读] 颜色迁移-N维pdf迁移 文章: N-Dimensional Probability Density Function Transfer and its Application to C ...

  3. 一张VR图像帧的生命周期

    "VR 应用程序每帧渲染两张图像,一张用于左眼,一张用于右眼."人们通常这样来解释 VR 渲染,虽然没有错,但可能过于简单化了.对于 Quest 开发人员来说,了解全貌是有益的,这 ...

  4. linux 使用ACR122U-A9设备读写M1卡

    前言 很久之前我在windows用过这个ACR122U-A9设备, 还挺好用,但是换了linux后,突然想又想用这个设备又是一顿折腾- 关于这个设备 其实这个设备只能读取M1卡(水卡这种),当时什么都 ...

  5. day13 I/O流——字节输入输出流、字符输入输出流 & File常用类 & (字节)复制大文件

    day13 I/O流 定义:数据在两设备传输称为流,流是一组有顺序的,有起点和终点的字节集合 I 是input的缩写,表示输入流 O是output缩写,表示输出流 字节流(视频等) 输入InputSt ...

  6. Excel2010工作簿被锁定,无法复制或者新增加sheet表格。

    Sub 工作簿密码破解() ActiveWorkbook.Sheets.Copy For Each sh In ActiveWorkbook.Sheets sh.Visible = True Next ...

  7. 环境安装-Centos7.4安装及配置

    环境安装-Centos7.4安装及配置 〇.资料汇总 一.虚拟机安装 1.下载地址 https://pan.baidu.com/s/1zcOp06HX4OxPdsCCGkHbXQ 提取码:7777 2 ...

  8. 单点登录系统使用Spring Security的权限功能

    背景 在配置中心增加权限功能 目前配置中心已经包含了单点登录功能,可以通过统一页面进行登录,登录完会将用户写入用户表 RBAC的用户.角色.权限表CRUD.授权等都已经完成 希望不用用户再次登录,就可 ...

  9. 秒级查询之开源分布式SQL查询引擎Presto实操-上

    @ 目录 概述 定义 概念 架构 优缺点 连接器 部署 集群安装 常用配置说明 资源管理安装模式 安装命令行界面 基于Tableau Web 连接器 使用优化 数据存储 查询SQL优化 无缝替换Hiv ...

  10. AStar寻路算法示例

    概述 AStar算法是一种图形搜索算法,常用于寻路.他是以广度优先搜索为基础,集Dijkstra算法和最佳优先(best fit)于一身的一种算法. 示例1:4向 示例2:8向 思路 递归的通过估值函 ...