#P16397. 虫群分解

虫群分解

题目背景

Jessie 有一张矩形网格图,其中每个格子都属于某一条“虫”。她原本想把整张图打印出来,但打印机在按行逐格打印的过程中耗尽了墨水,因此你只能看到打印内容的一个前缀。

已经打印出的字母描述了部分虫的形状:相同字母对应同一条虫,不同字母对应不同的虫;尚未打印的格子使用 ? 表示。请根据这些残缺的信息,计算有多少种完整的虫群分解与之匹配。

题目描述

在方格网格上,一条虫是一个由一个或多个格子组成的序列。除第一个格子外,序列中的每个格子都必须位于前一个格子的正下方正左方

一个矩形的虫群分解,是由若干条互不相交的虫组成的集合,并且这些虫所包含的格子恰好覆盖整个矩形。

给定一个矩形 printed,其中:

  • 小写英文字母 az 表示已经打印出的格子;
  • ? 表示尚未打印出的格子;
  • 标有相同字母的所有格子属于同一条虫;
  • 标有不同字母的格子属于不同的虫。

打印机按照从上到下、每行从左到右的顺序逐格打印。因此,将所有格子按上述顺序排列后,所有已经打印的字母必定构成该序列的一个前缀,其余格子全部为 ?

字母只用于描述输入中已经打印出的部分。原始的完整虫群分解可以包含任意多条虫,并不局限于 26 条。

如果两条虫所包含的格子集合不同,则认为它们是不同的虫。如果两个虫群分解所包含的虫集合不同,则认为它们是不同的虫群分解。

请计算所有与 printed 匹配的完整虫群分解数量,并对 (10^9+7) 取模。

输入格式

第一行包含两个整数 (H,W),分别表示矩形的行数和列数。

接下来 (H) 行,每行包含一个长度为 (W) 的字符串,表示 printed

输出格式

输出一个整数,表示与 printed 匹配的虫群分解数量对 (10^9+7) 取模后的结果。

样例 1

输入

2 2
x?
??

输出

9

解释

打印机只打印出了左上角的一个格子。单独出现的字母 x 不会对虫群分解施加额外限制,因此需要统计整个 (2\times 2) 矩形的所有虫群分解,共有 (9) 种。

样例 2

输入

1 3
???

输出

4

解释

一行三个格子可以组成一条虫、两条虫或三条虫。其中,分成两条虫有两种方法,因此答案为 (4)。

样例 3

输入

5 4
aabb
bbby
bxyy
bxyq
qqqq

输出

1

解释

注意,样例中的 q 是小写英文字母,而不是问号 ?

所有格子都已经打印,给出的字母恰好描述了一个合法的虫群分解,因此答案为 (1)。

数据范围

  • (1\le H\le 50);
  • (1\le W\le 50);
  • 每一行字符串的长度均为 (W);
  • 每个字符均为小写英文字母或 ?
  • 按照行优先顺序排列所有格子后,所有字母构成一个前缀,所有 ? 构成一个后缀;
  • 保证至少存在一种与输入匹配的虫群分解。