ICode9

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

矩阵游戏

2022-09-14 00:00:44  阅读:277  来源: 互联网

标签:游戏 int ll 矩阵 ans mul Matrix


矩阵游戏

是一道题;
正好拿来练矩阵乘法;

题目传送门 https://www.luogu.com.cn/problem/P1397

显然老老实实的递推挂了;
那么 很容易想到矩阵加速
如何从F(1,1)转换到F(n,m)
每一列进行m-1次乘a加b的操作A
每一行进行n-1次乘c加d的操作B

可得 F(i,n)=F(i,1)* ( A^(m-1)); (^表示次方)
同理
每一行F(n,1)=F(1,1)*(B^(n-1);
对于每一项记为ans,开始时为|1 , 1|

每一行递推项A, 则为
|a , 0|
|b , 1|
同理每一列B,则为
|c , 0|
|d , 1| 矩阵乘法手推一下啦;
由此可得
F(n,m)=F(1,1)* [(A(m-1)***B**)(n-1)] * A^(m-1)

有了大好的公式,接下来就是喜闻乐见的代码了

#include<bits/stdc++.h>
#define mod 1000000007
#define phi 1000000006
using namespace std;
typedef long long ll;
string n,m;
ll a,b,c,d;
struct Matrix
{ 
	ll a[5][5]; 
	Matrix() {memset(a,0,sizeof(a));}
};
Matrix mul(Matrix A,Matrix B)
{
	Matrix ans;
	for(int i=1;i<=2;i++)
		for(int j=1;j<=2;j++)
			for(int k=1;k<=2;k++)
			{
				ans.a[i][j]+=(A.a[i][k]*B.a[k][j])%mod;
				ans.a[i][j]%=mod;	
			}
	return ans;
}
Matrix qpow(Matrix a,ll b)
{
	Matrix tmp;
	for(int i=1;i<=2;i++) tmp.a[i][i]=1;
	for(;b;b>>=1)
	{
		if(b&1) tmp=mul(tmp,a);
		
		a=mul(a,a);
	}
	return tmp;
}

int main()
{
	cin>>n>>m;
	Matrix A,B,ans,Ans;
	scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
	ll ln=n.size(),lm=m.size(),nans=0,mans=0;
	
	Ans.a[1][1]=1; Ans.a[1][2]=1;
	A.a[1][1]=a, A.a[1][2]=0, A.a[2][1]=b, A.a[2][2]=1;
	B.a[1][1]=c, B.a[1][2]=0, B.a[2][1]=d, B.a[2][2]=1;
	
	for(int i=0;i<ln;i++)
	nans=(nans<<3)+(nans<<1)+n[i]-'0',nans%=(a==1?mod:phi);//细节1
	for(int i=0;i<lm;i++)
	mans=(mans<<3)+(mans<<1)+m[i]-'0',mans%=(c==1?mod:phi);

//	cout<<nans<<" "<<mans<<endl;
	
	A=qpow(A,mans-1);
//	cout<<A.a[1][1]<<endl;
	B=mul(B,A);//细节2
	B=qpow(B,nans-1);
	A=mul(A,B);
//	cout<<B.a[1][1]<<endl;
	ans=mul(Ans,A);
	printf("%lld\n",ans.a[1][1]);
	return 0;
}
### 细节一
有~~小定理说过~~ a^b与a^b%phi(p)在p意义下同余,phi这时就是p-1(p为素数)
对于a=1或c=1时 
此时特殊考虑
整个式子变为一次项且只与b和d有关
那就不如直径%p好了

### 细节二
矩阵乘法是没有交换律的
乘的时候注意行列顺序

标签:游戏,int,ll,矩阵,ans,mul,Matrix
来源: https://www.cnblogs.com/llwwll/p/16691461.html

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

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

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

ICode9版权所有