题目描述

金企鹅同学非常擅长用 1×21×21×2 的多米诺骨牌覆盖棋盘的题。有一天,正在背四六级单词的他忽然想:既然两个格子的积木叫“多米诺 (domino)”,那么三个格子的的积木一定叫“三米诺 (tromino)”了!用三米诺覆盖棋盘的题怎么做呢?

用三米诺覆盖 3×n3×n3×n 的矩形棋盘,共多少种方案?三米诺可旋转;两种方案不同当且仅当这两种图案直接覆盖在一起无法重叠。

例如 n=2n=2n=2 时,共 333 种方案:

输入输出格式

输入格式

一行一个整数 n(n≤1040000)n(n≤10^{40000})n(n≤1040000),表示棋盘列数。

输出格式

一行一个整数,表示方案数,对 998244353998244353998244353 取模。

输入输出样例

输入样例#1:

2

输出样例#1:

3

输入样例#2:

3

输出样例#2:

10

输入样例#3:

29

输出样例#3:

543450786

解题分析

我们手玩一波样例, 考虑新一行第iii行从前面某一行完整地转移过来(即是两个矩形拼接到一起的形式)

  • 从i−1i-1i−1行转移:只可能是下面这种情况, 所以dp[i]+=dp[i−1]dp[i]+=dp[i-1]dp[i]+=dp[i−1]:

  • 从第i−2i-2i−2行转移: 如果放竖着的可以归纳到i−1i-1i−1行中, 我们不再计算。 于是有下面两种情况:

    然后我们发现似乎这个可以引出更多的转移:

    (对称的并没有画出来)

    类似这样的我们同一归到从i−(3n+2)i-(3n+2)i−(3n+2)行转移中, 这样我们可以维护一个sum[3]sum[3]sum[3]记录下标mod3mod\ 3mod 3分别等于0,1,20,1,20,1,2的答案的前缀和。 这样的话dp[i]+=2×sum[(i−2)mod3]dp[i]+=2\times sum[(i-2)\ mod \ 3]dp[i]+=2×sum[(i−2) mod 3]。

  • 从第i−3i-3i−3行转移, 这样可以引出这样一类, 有四种同构:

即从i−3ni-3ni−3n行转移, 这样的话dp[i]+=sum[imod3]dp[i]+=sum[i\ mod\ 3]dp[i]+=sum[i mod 3]

我们发现似乎sum[(i−1)mod3]sum[(i - 1)\ mod\ 3]sum[(i−1) mod 3]没有用到, 于是再画图就可以发现有这样一种情况:

当然这样也会有对称的情况, 但我们发现从i−1i-1i−1转移的情况也包含在了这个前缀和里面, 而它只能算一次, 所以我们最后需要减掉。

当然从i−3i-3i−3转移还有一种特殊情况:

这个单独算上就好了。

最后的dpdpdp方程就是:
dp[i]=−dp[i−1]+sum[(i−1)mod3]×2+dp[i−3]+sum[imod3]×4+sum[(i−2)mod3]×2dp[i]=-dp[i-1]+sum[(i-1)\ mod\ 3]\times 2+dp[i-3]+sum[i\ mod\ 3]\times 4+sum[(i-2)\ mod\ 3]\times 2 dp[i]=−dp[i−1]+sum[(i−1) mod 3]×2+dp[i−3]+sum[i mod 3]×4+sum[(i−2) mod 3]×2
套上一个矩阵, 十进制快速幂, 完美ACACAC。

代码如下:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cctype>
#include <cmath>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define ll long long
#define MOD 998244353
struct Matrix
{ll mat[6][6];void clear() {std::memset(mat, 0, sizeof(mat));}
}base, res, ans;
IN Matrix operator * (const Matrix &x, const Matrix &y)
{Matrix ret; ret.clear();for (R int i = 0; i < 6; ++i)for (R int j = 0; j < 6; ++j)for (R int k = 0; k < 6; ++k)ret.mat[i][k] = ret.mat[i][k] + 1ll * x.mat[i][j] * y.mat[j][k];for (R int i = 0; i < 6; ++i)for (R int j = 0; j < 6; ++j) ret.mat[i][j] %= MOD;return ret;
}
char buf[40050];
int len;
IN void True_fpow(Matrix &tar, Matrix res, R int tm)
{W (tm){if(tm & 1) tar = tar * res;res = res * res; tm >>= 1;}
}
IN void fpow()
{Matrix emp = base, unit = base;for (R int i = len; i; --i){True_fpow(base, res, buf[i] - '0');unit = emp;True_fpow(unit, res, 10);res = unit;}
}
void dealit()
{R int pos = len;if(buf[pos] >= '2') return buf[pos] -= 2, void();--pos; W (buf[pos] == '0') --pos;--buf[pos]; for (R int i = pos + 1; i < len; ++i) buf[i] = '9';buf[len] += 8;
}
int main(void)
{res = (Matrix){ -1, 0, 1, 4, 2, 2,//转移矩阵1, 0, 0, 0, 0, 0,0, 1, 0, 0, 0, 0,0, 0, 0, 0, 1, 0,0, 0, 0, 0, 0, 1,-1, 0, 1, 5, 2, 2};base = (Matrix){1, 0, 0, 0, 0, 0,0, 1, 0, 0, 0, 0,0, 0, 1, 0, 0, 0,0, 0, 0, 1, 0, 0,0, 0, 0, 0, 1, 0,0, 0, 0, 0, 0, 1};//初始状态ans = (Matrix){ 3, 0, 0, 0, 0, 0,//dp[2]1, 0, 0, 0, 0, 0,//dp[1]1, 0, 0, 0, 0, 0,//dp[0]1, 0, 0, 0, 0, 0,//sum[0]1, 0, 0, 0, 0, 0,//sum[1]3, 0, 0, 0, 0, 0};//sum[2]scanf("%s", buf + 1); len = std::strlen(buf + 1);if(len == 1 && buf[1] == '1') return puts("1"), 0;if(len == 1 && buf[1] == '2') return puts("3"), 0;dealit();fpow();printf("%d", ((base * ans).mat[0][0] + MOD) % MOD);
}

九校联考-DL24 凉心模拟 Day1T3 三米诺 (tromino)相关推荐

  1. 九校联考-DL24凉心模拟Day1T3 三米诺 (tromino)

    题目背景 金企鹅同学非常擅长用1*2的多米诺骨牌覆盖棋盘的题.有一天,正 在背四六级单词的他忽然想:既然两个格子的积木叫"多米诺(domino)",那 么三个格子的的积木一定叫&q ...

  2. 九校联考-DL24凉心模拟Day2T1 锻造(forging)

    1.1 题目背景 勇者虽然武力值很高,但在经历了多次战斗后,发现怪物越来越难打 于是开始思考是不是自己平时锻炼没到位,于是苦练一个月后发现......自己连一个史莱姆都打不过了. 勇者的精灵路由器告诉 ...

  3. 九校联考-DL24 凉心模拟 Day2T1 锻造 (forging)

    题目描述 勇者虽然武力值很高,但在经历了多次战斗后,发现怪物越来越难打,于是开始思考是不是自己平时锻炼没到位,于是苦练一个月后发现--自己连一个史莱姆都打不过了. 勇者的精灵路由器告诉勇者其实是他自己 ...

  4. 【九校联考-24凉心模拟】锻造(forging)

    题目背景 勇者虽然武力值很高,但在经历了多次战斗后,发现怪物越来越难打, 于是开始思考是不是自己平时锻炼没到位,于是苦练一个月后发现--自 己连一个史莱姆都打不过了. 勇者的精灵路由器告诉勇者其实是他 ...

  5. 九校联考-长沙市一中NOIP模拟Day1T3 优美序列(sequence)

    问题描述 Lxy养了N头奶牛,他把N头奶牛用1..N编号,第i头奶牛编号为i.为了让奶牛多产奶,每天早上他都会让奶牛们排成一排做早操.奶牛们是随机排列的.在奶牛排列中,如果一段区间[L,R]中的数从小 ...

  6. 九校联考-长沙市一中NOIP模拟Day2T2 走格子(cell)

    问题描述 CYJ想找到他的小伙伴FPJ,.CYJ和FPJ现在位于一个房间里,这个房间的布置可以看成一个N行M列的矩阵,矩阵内的每一个元素会是下列情况中的一种: 障碍区域-这里有一堵墙(用'#'表示). ...

  7. 九校联考-长沙市一中NOIP模拟Day1T1 矩阵游戏(game)

    问题描述 LZK发明一个矩阵游戏,大家一起来玩玩吧,有一个N行M列的矩阵.第一行的数字是1,2,-M,第二行的数字是M+1,M+2-2M,以此类推,第N行的数字是(N-1)M+1,(N-1)M+2-N ...

  8. 九校联考-长沙市一中NOIP模拟Day2T1 旋转子段(rotate)

    问题描述 ZYL有N张牌编号分别为1, 2,--,N.他把这N张牌打乱排成一排,然后他要做一次旋转使得旋转后固定点尽可能多.如果第i个位置的牌的编号为i,我们就称之为固定点. 旋转可以被认为是将其中的 ...

  9. 九校联考-长沙市一中NOIP模拟Day2T3 柱状图(column)

    问题描述 WTH 获得了一个柱状图 , 这个柱状图一共有 N 个柱子 , 最开始第 i 根柱子的高度为 x i , 他现在要将这个柱状图排成一个屋顶的形状 , 屋顶的定义如下 : 屋顶存在一个最高的柱 ...

最新文章

  1. Redis配置文件中的三个参数
  2. leetcode算法题--Number of Islands
  3. SQL Inject of Code to bypass
  4. 《数据结构与算法》课程设计报告——赫夫曼编码/译码器
  5. ubuntu14.04设置静态IP
  6. (转)Akka学习笔记
  7. 心学 禅宗_禅宗宣言,用于有效的代码审查
  8. 样机|UI大佬用的样机,都在这里哦!
  9. WCF框架基础(一)
  10. 【渝粤教育】电大中专药物化学基础作业 题库
  11. Requests库常用方法及其详解
  12. 深度学习(四十二)网络压缩-未完待续
  13. python中字典的索引_python字典索引
  14. 前端答题小游戏_前端知识小游戏
  15. HDU6638 Snowy Smile
  16. 腾讯地图 周边 poi 搜索及参数配置
  17. Go语言框架Gin之4 安全认证
  18. 微积分在金融投资的应用
  19. 明明价格下降了,为什么你却花了更多钱?
  20. 数据窗口控件的函数Describe()

热门文章

  1. PHP报错:Call to undefined function bcmul()即php-bcmath模块未正常工作
  2. 微信JS-SDK获取signature签名以及config配置(微信转发分享页面需要)
  3. 运行python文件、电脑突然黑屏_电脑突然黑屏怎么回事
  4. PyTorch中的padding操作
  5. 认识vue3.0项目的目录结构
  6. 解决Android 9 无法连接网络问题
  7. 纯java视频转图片,对图片换脸,再次图片合成视频,java视频换脸
  8. 使用canvas图片裁剪
  9. 查找逗号分隔串所有的对应值
  10. php后台进不去,PHP网站后台进不去。惆怅。