计蒜客模拟赛D2T1 蒜头君的兔子:矩阵快速幂
题目链接:https://nanti.jisuanke.com/t/16442
题意:
有个人在第一年送了你一对1岁的兔子。这种兔子刚生下来的时候算0岁,当它在2~10岁的时候,每年都会生下一对兔子,并且它在10岁那年生完兔子后就会挂掉。现在让你算出第t年兔子的总数(不算那一年10岁的兔子)。
题解:
我们用一个1*10的矩阵代表某一年的兔子数量,第k列上的数字n代表今年有n只k岁的兔子。
那么初始矩阵是这样的:

接下来考虑怎样构造特殊矩阵。
有两个转移关系:
第二年0岁的兔子数 = 第二年2~10岁的兔子数之和 = 今年1~9岁的兔子数之和
第二年k (1<=k<=10) 岁的兔子数 = 今年k-1岁的兔子数
也就是这样转移:

b[0] = a[1] + a[2] + ... + a[9]
b[1] = a[0]
b[2] = a[1]
...
b[9] = a[8]
b[10] = a[9]
那么特殊矩阵也就出来了:

所以第t年的矩阵ans = 初始矩阵start * ( 特殊矩阵special ^ (t-1) )
优化:由于在整个过程中根本没有用到每年10岁的兔子数量,所以可以省去初始矩阵的第10列,以及特殊矩阵的第10列&第10行。
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_L 15
#define MOD 1000000007 using namespace std; struct Mat
{
int n;
int m;
long long v[MAX_L][MAX_L];
Mat()
{
memset(v,,sizeof(v));
n=;
m=;
}
}; int t;
long long sum=; Mat make_unit(int k)
{
Mat mat;
mat.n=k;
mat.m=k;
for(int i=;i<k;i++)
{
mat.v[i][i]=;
}
return mat;
} Mat make_start()
{
Mat mat;
mat.n=;
mat.m=;
mat.v[][]=;
return mat;
} Mat make_special()
{
Mat mat;
mat.n=;
mat.m=;
for(int i=;i<=;i++)
{
mat.v[i][]=;
mat.v[i-][i]=;
}
return mat;
} Mat mul_mat(const Mat &a,const Mat &b)
{
Mat c;
c.n=a.n;
c.m=b.m;
for(int i=;i<a.n;i++)
{
for(int j=;j<b.m;j++)
{
for(int k=;k<a.m;k++)
{
c.v[i][j]+=(a.v[i][k]*b.v[k][j])%MOD;
c.v[i][j]%=MOD;
}
}
}
return c;
} Mat quick_pow_mat(Mat mat,long long k)
{
Mat ans;
ans=make_unit(mat.n);
while(k)
{
if(k&)
{
ans=mul_mat(ans,mat);
}
k>>=;
mat=mul_mat(mat,mat);
}
return ans;
} void read()
{
cin>>t;
} void solve()
{
Mat start=make_start();
Mat special=make_special();
Mat ans=mul_mat(start,quick_pow_mat(special,t-));
for(int i=;i<=;i++)
{
sum=(sum+ans.v[][i])%MOD;
}
} void print()
{
cout<<sum<<endl;
} int main()
{
read();
solve();
print();
}
计蒜客模拟赛D2T1 蒜头君的兔子:矩阵快速幂的更多相关文章
- 计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和
题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将 ...
- 计蒜客模拟赛D2T3 蒜头君救人:用bfs转移状压dp
题目链接:https://nanti.jisuanke.com/t/16444 题意: 蒜头君是一个乐于助人的好孩子,这天他所在的乡村发生了洪水,有多名村民被困于孤岛上,于是蒜头君决定去背他们离开困境 ...
- 计蒜客模拟赛D1T3 蒜头君的坐骑:用dfs转移dp
题目链接:https://nanti.jisuanke.com/t/16447 题意: 蒜头君有一只坐骑,人马. 一天,蒜头君骑着他的坐骑走上了一片n*m的大荒野,一开始时,蒜头君在(1,1)点,他要 ...
- 计蒜客模拟赛D2T2 蒜头君的排序:区间逆序对(移动端点) + 树状数组
题目链接:https://nanti.jisuanke.com/t/16443 题意: 给你一个由1~n构成的正整数序列,有m组询问,每组询问要求输出[l , r]区间内的逆序对个数. 数据范围: 对 ...
- 计蒜客模拟赛D1T2 蒜头君的树:树上节点之间最短距离和
题目链接:https://nanti.jisuanke.com/t/16446 题意: 给你一棵有n个节点的树以及每条边的长度,输出树上节点之间的最短距离和.然后进行m次操作,每次操作更改一条边的长度 ...
- 计蒜客模拟赛5 D2T1 成绩统计
又到了一年一度的新生入学季了,清华和北大的计算机系同学都参加了同一场开学考试(因为两校兄弟情谊深厚嘛,来一场联考还是很正常的). 不幸的是,正当老师要统计大家的成绩时,世界上的所有计算机全部瘫痪了. ...
- 计蒜客模拟赛5 D2T2 蚂蚁搬家
很久很久以前,有很多蚂蚁部落共同生活在一片祥和的村庄里.但在某一天,村庄里突然出现了一只食蚁兽,蚂蚁们为了保全性命而决定搬家. 然而这个村庄四面环山,想要离开这个村庄必须要从地洞里离开,村子里一共有 ...
- 计蒜客模拟赛 #5 (B 题) 动态点分治+线段树
虽然是裸的换根dp,但是为了在联赛前锻炼码力,强行上了点分树+线段树. 写完+调完总共花了不到 $50$ 分钟,感觉还行. code: #include <bits/stdc++.h> # ...
- 2019ICPC西安邀请赛(计蒜客复现赛)总结
开始时因为吃饭晚了一刻钟,然后打开比赛.看了眼榜单A题已经过了二十来个队伍了,宝儿就去做A. 传师说最后一题看题目像最短路,于是我就去看M了,宝儿做完之后也来陪我看.M一开始看到时以为是像 POJ ...
随机推荐
- CSS3学习系列之背景相关样式(二)
在border-radius属性中指定两个半径 在border-radius属性中,可以指定两个半径,指定方法如下所示: border-radius:40px 20px; 针对这种情况,各种浏览器的处 ...
- Linux文件属性上
文件属性概述(ls -lhi) linux里一切皆文件Linux系统中的文件或目录的属性主要包括:索引节点(inode),文件类型,权限属性,链接数,所归属的用户和用户组,最近修改时间等内容: 解释: ...
- .net core建站踩坑记录
系统:win10 VS版本:2017 .NET Core 版本: 1.1 零.读取配置文件 参考:http://www.tuicool.com/articles/QfYVBvi 此版本无需添加其他组件 ...
- Randoop测试类和方法(用例自动生成)
详细使用方法见randoop官网: https://randoop.github.io/randoop/manual/index.html 测试程序之前,先检测下你的Randoop是否配置好: 打开c ...
- RabbitMQ系列教程之六:远程过程调用(RPC)
远程过程调用(Remote Proceddure call[RPC])(本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习了如何使用工作队列在多个工作实例之间分配耗时的任务. ...
- java constructor 在构造子类时,一定会调用到父类的构造方法 “ 私有属性被继承了?”问题
” Error:Implicit super constructor Pet() is undefined. Must explicitly invoke another constructor “ ...
- 关于EF 通用增删改查的封装
1. Entity Framework是Microsoft的ORM框架,随着 Entity Framework 不断的完善强化已经到达了EF 6.0+ 还是非常的完善的,目前使用的比例相对于其他OR ...
- 用户代理字符串(navigator.userAgent)检测方法
最近在看<JavaScript 高级程序设计(第三版)>,发现其中关于用户代理字符串检测技术的一些方法,觉得讲的很详细.用户代理字符串(navigator.userAgent)中包含了大量 ...
- java Static的使用
static是一个静态修饰符,用于修饰成员(成员变量,成员函数).<thinking in java>对staic的使用场景有下面2种定义:“一种情形是只想用一个存储区域来保存一个特定的数 ...
- Invert a binary tree 翻转一棵二叉树
Invert a binary tree 翻转一棵二叉树 假设有如下一棵二叉树: 4 / \ 2 7 / \ / \ 1 3 6 9翻转后: 4 / \ 7 ...