ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P1397 [NOI2013] 矩阵游戏 题解

2022-07-18 13:31:57  阅读:157  来源: 互联网

标签:begin end P1397 题解 矩阵 times bmatrix NOI2013 equiv


P1397 [NOI2013] 矩阵游戏 题解

首先考虑 \(F_{n,m}\) 是怎么由 \(F_{1,1}\) 递推到的

考虑用矩阵优化两个递推式子,那么

\[\begin{bmatrix} F_{i,j-1}&1 \end{bmatrix} \times\begin{bmatrix}a & 0 \\ b & 1\end{bmatrix}=\begin{bmatrix} F_{i,j}&1 \end{bmatrix} \]

\[\begin{bmatrix} F_{i-1,m}&1 \end{bmatrix} \times\begin{bmatrix}c & 0 \\ d & 1\end{bmatrix}=\begin{bmatrix} F_{i,1}&1 \end{bmatrix} \]

显然,最后结果矩阵就等于:

\[\begin{bmatrix} 1&1 \end{bmatrix} \times (\begin{bmatrix}a & 0 \\ b & 1\end{bmatrix}^{m-1}\times\begin{bmatrix}c & 0 \\ d & 1\end{bmatrix})^{n-1}\times\begin{bmatrix}a & 0 \\ b & 1\end{bmatrix}^{m-1} \]

但是由于 \(1\le n,m\le10^{1000000}\) ,我们需要一些优化

矩阵费马小定理

对于矩阵:\((a,b,p\text{为常数})\)

\[\begin{bmatrix} a & 0 \\ b & 1 \end{bmatrix} \]

当 \(a\ne 1\) 时,显然有:

\[\begin{bmatrix}a & 0 \\ b & 1\end{bmatrix}^{p-1} = \begin{bmatrix}a^{p-1} & 0 \\ b\cdot(a^0+a^1+\cdots+a^{p-2}) & 1\end{bmatrix} \]

若 \(a,p\) 互质,则由费马小定理可得:

\[a^{p-1}\equiv 1\pmod p \]

\[b\cdot(a^0+a^1+\cdots+a^{p-2})\equiv b\cdot\frac{1-a^{p-1}}{1-a}\equiv b\cdot 0\equiv 0\pmod p \]

所以就可以得到:

\[\begin{bmatrix}a & 0 \\ b & 1\end{bmatrix}^{p-1}\equiv\begin{bmatrix}1 & 0 \\ 0 & 1\end{bmatrix}\pmod p \]

这样可以得到单位矩阵,性质十分优美

解法

考虑利用矩阵费马小定理,实际上

\[\begin{bmatrix}a & 0 \\ b & 1\end{bmatrix}^{m-1}=\begin{bmatrix}a & 0 \\ b & 1\end{bmatrix}^{(m-1)\bmod (p-1)} \]

其中 \(p=10^9+7\)

这样我们只需要预处理出 \((m-1)\bmod (p-1),(n-1)\bmod (p-1)\) 就行了

但是 \(a=1\) 或 \(c=1\) 时要特判

code

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define int long long

const int p=1e9+7;
const int N=1e6+5;

inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}

inline void add(ll &x,ll y){
	x=(x+y)%p;
}

struct matrix{
	int n;
	ll A[2][2];
	inline matrix(int x){n=x;memset(A,0,sizeof(A));}
	inline void operator ~(){
		for(int i=0;i<n;++i) A[i][i]=1;
	}
	inline matrix operator *(const matrix &B) {
		matrix C(n);
		for(int i=0;i<n;++i)
			for(int j=0;j<n;++j)
				for(int k=0;k<n;++k)
					add(C.A[i][k],A[i][j]*B.A[j][k]);
		return C;
	}
	inline matrix operator ^(const ll &idx) {
		matrix B(n),D=*this;
		~B;
		for(ll q=idx;q;q/=2,D=D*D)
			if(q&1) B=B*D;
		return B;
	}
};

ll n,m,a,b,c,d;
char s1[N],s2[N];

signed main(){
	scanf("%s",s1+1);
	scanf("%s",s2+1);
	a=read(),b=read(),c=read(),d=read();
	int len1=strlen(s1+1),len2=strlen(s2+1);
	for(int i=1;i<=len1;++i)
		n=((n<<1)+(n<<3)+(s1[i]^48))%(p-(a!=1));
	for(int i=1;i<=len2;++i)
		m=((m<<1)+(m<<3)+(s2[i]^48))%(p-(c!=1));
	matrix A(2),B(2),x(2),y(2); 
	A.A[0][0]=a,A.A[0][1]=0,A.A[1][0]=b,A.A[1][1]=1;
	B.A[0][0]=c,B.A[0][1]=0,B.A[1][0]=d,B.A[1][1]=1;
	x=A^(m-1);
	B=x*B;
	y=B^(n-1);
	x=y*x;
	cout<<(x.A[0][0]+x.A[1][0])%p;
}

标签:begin,end,P1397,题解,矩阵,times,bmatrix,NOI2013,equiv
来源: https://www.cnblogs.com/into-qwq/p/16490097.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有