Luogu T7152 细胞(递推,矩阵乘法,快速幂)
Luogu T7152 细胞(递推,矩阵乘法,快速幂)
Description
小 X 在上完生物课后对细胞的分裂产生了浓厚的兴趣。于是他决定做实验并
观察细胞分裂的规律。
他选取了一种特别的细胞,每天每个该细胞可以分裂出 x − 1 个新的细胞。
小 X 决定第 i 天向培养皿中加入 i 个细胞(在实验开始前培养皿中无细胞)。
现在他想知道第 n 天培养皿中总共会有多少个细胞。
由于细胞总数可能很多,你只要告诉他总数对 w 取模的值即可。
Input
第一行三个正整数 n, x,w
Output
一行一个数表示第 n 天的细胞总数对 w 取模的值。
Sample Input
2 2 47
Sample Output
4
Http
Luogu(团队私有题目):https://www.luogu.org/problem/show?pid=T7152
Source
递推,矩阵乘法,快速幂
解决思路
首先考虑数据范围较小的情况,令F[i]表示第i天培养皿中的细胞个数,那么我们可以轻易地推导出递推式:F[i]=x*F[i-1]+i
当然这样是过不了的,这道题的正确解法确实是递推,但是要用矩阵优化!
关于矩阵,可以到我的这篇文章:http://www.cnblogs.com/SYCstudio/p/7211050.html
我们在上面推出了递推式F[i]=x*F[i-1]+i,我们发现若要求出F[i]必须一遍一遍for,并且不能讲这个式子化简,若我们能找到一个式子F[i]=T*F[i-1],岂不美哉?这样我们就可以直接得到F[n]=F[1]*T^(n-1),这就可以用快速幂在logn范围内解决了。
矩阵正式这么一个美哉的式子,我们需要运用一些智慧来凑出T矩阵。
首先我们再回到F[i]=x*F[i-1]+i,这其中有两个变量F[i-1]和i,我们发现F[i-1]由F[i-2]推过来,而i则是每次递增常数1。所以,在把F变成矩阵后,我们可以确定这是一个三维矩阵,$$[原有细胞数,新加的细胞数,i递增的常数1]$$,例如第一天就是[0,1,1],第二天就是[1,2,1],第三天就是[x+2,3,1],为了方便叙述,我们把该矩阵补成3*3的,即$$\begin{bmatrix} 原有的细胞数 & 第i天新加的细胞数 & i的递增常数1 \ 0 & 0 & 0 \ 0 & 0 & 0 \end{bmatrix}$$
那么接下来就是脑补出T矩阵啦!
根据矩阵乘法的定义,我们可以得到T矩阵为:
\]
至于怎么得到的呢?说啦要靠脑补要靠从矩阵乘法的定义出发,用0和1来处理在某个位置是否要保留某个数,经过一系列yy然后我们就得到T啦。
接下来我们来检验一下T是否正确。
我们先有一个初值(即第一天)$$F_1=\begin{bmatrix} 0 & 1 & 1 \ 0 & 0 & 0 \ 0 & 0 & 0\end{bmatrix}$$
然后我们计算$$F_2=F_1T=\begin{bmatrix} 0 & 1 & 1 \ 0 & 0 & 0 \ 0 & 0 & 0\end{bmatrix}\begin{bmatrix} X & 0 & 0 \ 1 & 1 & 0 \ 0 & 1 & 1\end{bmatrix}=\begin{bmatrix} 1 & 2 & 1 \ 0 & 0 & 0 \ 0 & 0 & 0\end{bmatrix}$$
发现没有,F2的第一行的三个数正好是我们上面的$$[原有细胞数,新加的细胞数,i递增的常数1]$$
如果不信,我们再计算几个
\]
\]
\]
这里强烈建议自己手动模拟一下
矩阵快速幂
既然我们已经有了如此妙啊的矩阵,那我们如果用for循环一个一个累乘岂不是浪费才华吗?看到幂的形式了没有?我们可以把我们再整数幂计算时用到的快速幂算法运用到矩阵上来。
那么这里就是要对矩阵重载一下*运算符就可以了,其他地方均与整数快速幂一致。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
ll n,X,Mod;
class Matrix//定义一个矩阵结构体
{
public:
ll M[3][3];
Matrix()//初始化0
{
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
M[i][j]=0;
}
Matrix(ll Arr[3][3])//用数组来初始化
{
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
M[i][j]=Arr[i][j];
}
};
Matrix operator * (Matrix A,Matrix B)//重载乘法运算符
{
Matrix Ans;
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
for (int k=0;k<3;k++)
Ans.M[i][j]=(Ans.M[i][j]+A.M[i][k]*B.M[k][j]%Mod)%Mod;
return Ans;
}
const int inf=2147483647;
ll Pow();
int main()//无比简单的主函数
{
cin>>n>>X>>Mod;
cout<<Pow()<<endl;
return 0;
}
ll Pow()//矩阵快速幂
{
ll a[3][3]={{0,1,1},{0,0,0},{0,0,0}};//初始状态
ll b[3][3]={{X,0,0},{1,1,0},{0,1,1}};//用来使状态发生转移的矩阵,即文中提到的T
Matrix A(a);
Matrix B(b);
while (n!=0)
{
if (n&1)
{
A=A*B;//注意这里的乘法顺序,矩阵乘法不满足交换律
}
B=B*B;
n=n>>1;
}
return A.M[0][0];//根据我们的定义,最后的值就在A.M[0][0]
}
如果对你有帮助就点个赞吧!
同时欢迎大佬到右边或下面发言指错。
Luogu T7152 细胞(递推,矩阵乘法,快速幂)的更多相关文章
- 【BZOJ 2323】 2323: [ZJOI2011]细胞 (DP+矩阵乘法+快速幂*)
2323: [ZJOI2011]细胞 Description 2222年,人类在银河系外的某颗星球上发现了生命,并且携带了一个细胞回到了地球.经过反复研究,人类已经完全掌握了这类细胞的发展规律: 这种 ...
- Qbxt 模拟赛 Day4 T2 gcd(矩阵乘法快速幂)
/* 矩阵乘法+快速幂. 一开始迷之题意.. 这个gcd有个规律. a b b c=a*x+b(x为常数). 然后要使b+c最小的话. 那x就等于1咯. 那么问题转化为求 a b b a+b 就是斐波 ...
- 洛谷 P4910 帕秋莉的手环 矩阵乘法+快速幂详解
矩阵快速幂解法: 这是一个类似斐波那契数列的矩乘快速幂,所以推荐大家先做一下下列题目:(会了,差不多就是多倍经验题了) 注:如果你不会矩阵乘法,可以了解一下P3390的题解 P1939 [模板]矩阵加 ...
- [LOJ3086][GXOI/GZOI2019]逼死强迫症——递推+矩阵乘法
题目链接: [GXOI/GZOI2019]逼死强迫症 设$f[i][j]$表示前$i$列有$j$个$1*1$的格子的方案数,那么可以列出递推式子: $f[i][0]=f[i-1][0]+f[i-2][ ...
- ACM学习历程—HDU5667 Sequence(数论 && 矩阵乘法 && 快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=5667 这题的关键是处理指数,因为最后结果是a^t这种的,主要是如何计算t. 发现t是一个递推式,t(n) = c ...
- codevs1281 矩阵乘法 快速幂 !!!手写乘法取模!!! 练习struct的构造函数和成员函数
对于这道题目以及我的快速幂以及我的一节半晚自习我表示无力吐槽,, 首先矩阵乘法和快速幂没必要太多说吧,,嗯没必要,,我相信没必要,,实在做不出来写两个矩阵手推一下也就能理解矩阵的顺序了,要格外注意一些 ...
- 矩阵乘法快速幂 codevs 1732 Fibonacci数列 2
1732 Fibonacci数列 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 在“ ...
- ACM学习历程—SNNUOJ 1116 A Simple Problem(递推 && 逆元 && 组合数学 && 快速幂)(2015陕西省大学生程序设计竞赛K题)
Description Assuming a finite – radius “ball” which is on an N dimension is cut with a “knife” of N- ...
- 【bzoj3231】[Sdoi2008]递归数列 矩阵乘法+快速幂
题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj ...
- [vijos1725&bzoj2875]随机数生成器<矩阵乘法&快速幂&快速乘>
题目链接:https://vijos.org/p/1725 http://www.lydsy.com/JudgeOnline/problem.php?id=2875 这题是前几年的noi的题,时间比较 ...
随机推荐
- 容器扩展属性 IExtenderProvider 实现WinForm通用数据验证组件
大家对如下的Tip组件使用应该不陌生,要想让窗体上的控件使用ToolTip功能,只需要拖动一个ToolTip组件到窗口,所有的控件就可以使用该功能,做信息提示. 本博文要记录的,就是通过容器扩展属性 ...
- 简单VR照片 使用陀螺仪、姿态角(Roll、Pitch、Yaw )、四元数
最近在做一个类似VR照片的demo,跟全景图片也很像,只是VR照片与全景720度显示,我只做了180度.但我发现他们实现的原理有一丝相似,希望可以给一些想入行AR.VR的朋友一些提示吧. ...
- VR全景,零售业冬天里的一把火——全景智慧城市
对今天的中国来说,寻找经济转型的突破口,寻找经济权力的新霸主,零售业应该当仁不让. 零售业正在经历一场脱胎换骨的改造.一方面零售额达到前所未有的水平,另一方面,传统零售商也面临诸多挑战,其中之一,便是 ...
- 磁盘文件I/O,SSD结构,局部性原理 笔记
磁盘文件I/O过程 进程向内核发起read scene.dat请求: 内核根据inode获取对应该进程的address space,在address space查找page_cache,如果没有找到, ...
- XCode 8.3 Automatically manage signing 问题
记录iOS证书问题 无意中选择了Personal team,后台自动生成bundle identifier:com.xxx.project,导致不能在Organization team创建,而且在de ...
- mysql之 mysql 5.6不停机主从搭建(一主一从基于GTID复制)
环境说明:版本 version 5.6.25-log 主库ip: 10.219.24.25从库ip:10.219.24.22os 版本: centos 6.7已安装热备软件:xtrabackup 防火 ...
- node.js零基础详细教程(5):express 、 路由
第五章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...
- php 可变函数
//可变函数 function Test(){ $arr = func_get_args(); //获取所有参数 ,返回数组 $sum=0; for($i ...
- 12.ThreadPoolExecutor线程池原理及其execute方法
jdk1.7.0_79 对于线程池大部分人可能会用,也知道为什么用.无非就是任务需要异步执行,再者就是线程需要统一管理起来.对于从线程池中获取线程,大部分人可能只知道,我现在需要一个线程来执行一个任 ...
- angularJS loading 载入画面
在请求网络的时候,显示loading画面 1. 使用http的interceptor,截断处理所有的http请求和响应,以及错误.在request的时候设置$rootScope.loading=Tru ...