10.02 T3 打表找递推式+十进制快速幂 九校联考凉心模拟DAY1T1

题目背景

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

题目描述

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

输入输出格式

输入格式:

一行一个整数n(n<=10^40000),表示棋盘列数。

输出格式:

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

输入输出样例

输入样例#1

2

输出样例#1

3

输入样例#2

3

输出样例#2

10

输入样例#3

29

输出样例#3

543450786

说明

对于10% 的数据,n <=5;
对于30% 的数据,n <=10^6;
对于40% 的数据,n <=20001000;
对于60% 的数据,n <=10^9;
对于80% 的数据,n <=10^1000
对于100% 的数据,n<=10^40000。

这题先爆搜把前面几项打表出来,然后上OEIS高斯消元把各项系数求出来,设a(n)为填满前n列的方案最后其实你可以得到一个东西

很显然直接上矩阵快速幂就可以了

但是数字这么大没法快速幂,发现一般的快速幂是2进制,我们就写十进制快速幂套一个二进制快速幂就可以了,其实我写了很久好难啊woc怎么会有这种东西就是按位快速幂就可以了(逃

取模多加点数字。。。负数把我坑惨了,顺便因为前六项只能打表,所以矩阵要乘n-6次,但字符串不好操作于是乘上6次矩阵的逆就可以了

code:

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 using namespace std;
  5 const long long mod=998244353;
  6 struct matrix{
  7     long long a[7][7];
  8 };
  9 long long chang[7][7]={
 10     {0,0,0,0,0,0,0},
 11     {0,1,1,0,0,0,0},
 12     {0,2,0,1,0,0,0},
 13     {0,6,0,0,1,0,0},
 14     {0,1,0,0,0,1,0},
 15     {0,0,0,0,0,0,1},
 16     {0,-1,0,0,0,0,0},
 17 };
 18 long long fan[7][7]={
 19     {0,0,0,0,0,0,0},
 20     {0,0,0,0,0,0,-1},
 21     {0,1,0,0,0,0,1},
 22     {0,0,1,0,0,0,2},
 23     {0,0,0,1,0,0,6},
 24     {0,0,0,0,1,0,1},
 25     {0,0,0,0,0,1,0},
 26 };
 27 matrix mul(matrix a,matrix b){
 28     matrix c;
 29     memset(c.a,0,sizeof c.a);
 30     for(long long i=1;i<=6;i++){
 31         for(long long j=1;j<=6;j++){
 32             for(long long k=1;k<=6;k++){
 33                 c.a[i][j]+=(a.a[i][k]%mod*b.a[k][j])%mod;
 34                 c.a[i][j]%=mod;
 35             }
 36         }
 37     }
 38     return c;
 39 }
 40 matrix ksm(matrix a,long long b){
 41     matrix ans;
 42     memset(ans.a,0,sizeof ans.a);
 43     ans.a[1][1]=ans.a[2][2]=ans.a[3][3]=ans.a[4][4]=ans.a[5][5]=ans.a[6][6]=1;
 44     for(;b;b>>=1){
 45     //    cout<<b<<‘\n‘;
 46         if(b&1)ans=mul(ans,a);
 47         a=mul(a,a);
 48     }
 49     return ans;
 50 }
 51 void tiaoshi(matrix ans){
 52         for(long long i=1;i<=6;i++){
 53         for(long long j=1;j<=6;j++)
 54         cout<<ans.a[i][j]<<" ";
 55         cout<<‘\n‘;
 56     }
 57 }
 58 int main(){
 59     freopen("tromino.in","r",stdin);
 60     freopen("tromino.out","w",stdout);
 61     string n;
 62     cin>>n;
 63     if(n.size()==1&&n[0]<=‘6‘){
 64         if(n=="1")cout<<1;
 65         if(n=="2")cout<<3;
 66         if(n=="3")cout<<10;
 67         if(n=="4")cout<<23;
 68         if(n=="5")cout<<62;
 69         if(n=="6")cout<<170;
 70         return 0;
 71     }
 72     matrix base,ans;
 73     memset(ans.a,0,sizeof ans.a);
 74     memset(base.a,0,sizeof base.a);
 75     for(long long i=1;i<=6;i++)
 76         for(long long j=1;j<=6;j++)
 77             base.a[i][j]=chang[i][j];
 78     ans.a[1][1]=ans.a[2][2]=ans.a[3][3]=ans.a[4][4]=ans.a[5][5]=ans.a[6][6]=1;
 79 //    for(long long i=1;i<=6;i++){
 80 //        for(long long j=1;j<=6;j++)
 81 //        cout<<base.a[i][j]<<" ";
 82 //        cout<<‘\n‘;
 83 //    }
 84     for(long long i=n.size()-1;i>=0;i--){
 85         long long num=n[i]-‘0‘;
 86     //    tiaoshi(ans);
 87     //    cout<<‘\n‘;
 88     //    cout<<num<<endl;
 89         ans=mul(ans,ksm(base,num));
 90     //    tiaoshi(ans);
 91         base=ksm(base,10);
 92     }
 93     matrix ni;
 94     for(long long i=1;i<=6;i++)
 95         for(long long j=1;j<=6;j++)
 96             ni.a[i][j]=fan[i][j];
 97     for(long long i=1;i<=6;i++){
 98         ans=mul(ans,ni);
 99     }
100     cout<<(mod*3+ans.a[1][1]*170%mod+ans.a[2][1]*62%mod+ans.a[3][1]*23%mod+ans.a[4][1]*10%mod+ans.a[5][1]*3%mod+ans.a[6][1]*1%mod)%mod;
101     return 0;
102 }

优秀的复杂度(误

over

原文地址:https://www.cnblogs.com/saionjisekai/p/9742200.html

时间: 2024-11-29 09:29:18

10.02 T3 打表找递推式+十进制快速幂 九校联考凉心模拟DAY1T1的相关文章

[题解][SHOI2013]超级跳马 动态规划/递推式/矩阵快速幂优化

这道题... 让我见识了纪中的强大 这道题是来纪中第二天(7.2)做的,这么晚写题解是因为 我去学矩阵乘法啦啦啦啦啦对矩阵乘法一窍不通的童鞋戳链接啦 层层递推会TLE,正解矩阵快速幂 首先题意就是给你一个 n 行m 列 的格子图 一只马从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行. 题意很简单暴力dp的思路也很简单但是数据很恶心虽然远古一点,但毕竟是省选题 1 ≤ n ≤ 50,2 ≤ m ≤ 10^9 不过还是给了我们一点提示:n这么小? 总之我们先找出转移式对于每一个点

ACM学习历程—SNNUOJ 1110 A Simple Problem(递推 &amp;&amp; 逆元 &amp;&amp; 组合数学 &amp;&amp; 快速幂)(2015陕西省大学生程序设计竞赛K题)

Description Assuming a finite – radius “ball” which is on an N dimension is cut with a “knife” of N-1 dimension. How many pieces will the “ball” be cut into most?However, it’s impossible to understand the following statement without any explanation.L

[HDOJ2604]Queuing(递推,矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604 递推式是百度的,主要是练习一下如何使用矩阵快速幂优化. 递推式:f(n)=f(n-1)+f(n-3)+f(n-4),其中f(0)=2, f(1)=4, f(2)=6, f(3)=9. 当n>4时候,需要通过这个关系来递推. 构造矩阵这种东西我以前一直认为是很玄学的,但是如果深入研究的话不难发现其实也有规律可循.这是一个齐次递推式,很好构造. 我们希望通过如下矩阵(1)得到矩阵(2) | f(n

hihoCoder 1143 : 骨牌覆盖问题&#183;一(递推,矩阵快速幂)

[题目链接]:click here~~ 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题: 我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘.对于这个棋盘,一共有多少种不同的覆盖方法呢? 举个例子,对于长度为1到3的棋盘,我们有下面几种覆盖方式: 提示:骨牌覆盖 提示:如何快速计算结果 输入 第1行:1个整数N.表示棋盘长度.1≤N≤100,000,000 输出 第1行:1个整数,表示覆盖方案数 M

「常系数齐次线性递推」——矩阵快速幂的优化

引入: 对于递推方程: $$F(x) = \sum_{i=1}^k a_iF(x-i)$$ 我们显然会得到一个关于$F$的多项式求逆或者矩阵递推式,大多数情况下我们都是用后者,但是当$k$很大的时候,$k^3log n$的时间复杂度我们是吃不消的,那么自然我们的前人就搞出了一些优化. 特征多项式及Cayley-Hamilton定理: 一.特征多项式的定义: 设$A$是$n$阶矩阵,若数$\lambda$和非零列向量$x$使关系式$$Ax=\lambda x\;\;\;\;\;(1)$$ 成立,那

hdu2604 递推转换矩阵快速幂

刚开始还以为用位运算与或几下几个循环就搞定了,算着算着发现不行........ 还是一种固定的切题角度,我假设有长度为n,总的排列数位f(n),怎么算他呢?从后往前考虑,因为大多数情况,都是用前面的结果推后面的结果, 那么当第n位是m的时候,如果我知道f(n-1)等于多少,那么f(n-1)的排列+加一个m是不是就是f(n)的一部分解了?  对吧,以此类推,   当第n位为f的时候,可是fff,fmf不能连着 那是不是就剩下ffm,fmm的情况了,对于前者ffm,由于不能凑成ffmf的情况,所以只

矩阵乘法(四):分析问题,确定递推式,采用矩阵快速幂求解

应用矩阵快速幂运算可以解决递推问题.在实际应用中,有时候题目并没有直接给出递推式,需要认真分析问题,找出递推式,然后再利用矩阵快速幂运算加快问题的求解. [例1]程序阅读理解. 有如下的C语言程序: #include <stdio.h>int main(){     int n,m,f,i;     while(scanf("%d%d",&n,&m)!=EOF)     {           f=0;           for(i=1;i<=n;i

51nod1149 Pi的递推式

基准时间限制:1 秒 空间限制:131072 KB 分值: 640 F(x) = 1 (0 <= x < 4) F(x) = F(x - 1) + F(x - pi) (4 <= x) Pi = 3.1415926535..... 现在给出一个N,求F(N).由于结果巨大,只输出Mod 10^9 + 7的结果即可. Input 输入一个整数N(1 <= N <= 10^6) Output 输出F(N) Mod 10^9 + 7 Input示例 5 Output示例 3 数学问

Python的递推式构造列表(List comprehension)

介绍 我们在上一章学习了“Lambda 操作, Filter, Reduce 和 Map”, 但相对于map, filter, reduce 和lamdba, Guido van Rossum更喜欢用递推式构造列表(List comprehension).在这一章我们将会涵盖递推式构造列表(List comprehension)的基础功能. 递推式构造列表(List comprehension)是在Python 2.0中添加进来的.本质上,它是一种数学家用来实现众所周知标记集合的Python方式