CharacterBoard

题目描述

很久很久以前,有一个活泼可爱的小朋友,他拥有一个列的棋盘,行从上至下以编号,列从左至右以编号。

后来,有一个长者给了他一个长度为的字符串,并让小朋友以以下伪代码去填充这个棋盘

int cursor = 0;
for (int i = 0; i < 1000000000; i++)
    for (int j = 0; j < W; j++)
    {
        a[i][j] = s[cursor];
        cursor = (cursor + 1) % L;
    }

接着,小朋友在大棋盘中取出一个以为左上角,行数为,列数为的子矩阵

现在已知,以及取出的子矩阵,而对于那个用于循环节的字符串,连长度都不知道,更别提内容了,只知道 ,且只含有小写字母。小朋友想要猜出这个字符串究竟是啥。

于是问你有多少种可能的值,答案

数据范围

算法一

很容易发现,

也就是说,的每一个格子,都是对上一个特定格子的限制。

观察得,的存在没有任何意义,因为的改变只会导致串的旋转,那么不妨令,即

枚举,考虑一个理想化的情况:如果中的各个元素所限制的中的位置各不重复(说人话便是:只要,必有),则中有个位置是被钦定的,其余个位置是绝对自由的,则这个对答案的贡献是

然而现实并没有这么理想。

如果上的一个位置同时受到中多个元素的限制,那么:...

.......case 1:这多个限制有矛盾,那个这个对答案的贡献就是

.......case 2:如果这多个限制没有矛盾,多个限制就合并成一个限制。

对于一个不理想的,如果出现了矛盾,这个就无法贡献答案,否则,设个限制合并后变成了R个,则对答案的贡献就是

那么就得到了一个枚举,然后对于每一个,都用std::map < int, char >来对限制进行判矛盾和去重,时间复杂度为的算法。

算法二

看!算法一太简单粗暴了!这种级别的数字怎么能枚举呢?

然而呢,上述的不理想的的个数是较少的,对于上的一对元素,想象把大棋盘拉直成条状,则这对元素在拉直后的条状棋盘上相距,那么只要的某个约数,就是不理想的。

把所有不理想的单独按照算法一的简单粗暴的方法统计答案,剩下的都是理想的,可以用(公比为的)等比数列求和的方法,成段地统计答案。

我的题解写完了,谢谢大家的观看!

results matching ""

    No results matching ""