[NOI2013]矩阵游戏

做题时间:2022.7.4

给定正整数 a,b,c,d(a,b,c,d109) ,有一个 nm 列( 1n,m101000000 )的矩阵 F ,满足:

F1,1=1

Fi,j=aFi,j1+b(j1)

Fi,1=cFi1,m+d(i1)

Fn,mmod109+7 的值。

一行 n,m,a,b,c,d

一行一个数表示 Fn,mmod109+7

矩阵快速幂,欧拉函数

看数据范围可知要使用矩阵快速幂,同时递推式表明用第二个式子确定好当前行第1列的数字后,第m列的数字即可用第一个式子套矩阵快速幂快速求出,而下一行第1列的数字又和这一行第m列有关, 因此可以考虑将两个式子合并

  1. 第一个式子:

[Fi,j11][ab01]=[Fi,j1]

就有:

[Fn,m1][ab01]m1=[Fn,11]

这里我们发现,不能直接求出的 Fn,1 可以用第二个式子带入。

  1. 第二个式子:

[Fi1,m1][cd01]=[Fi,11]

就有:

[F1,m1][cd01]=[Fn,11]

这里我们发现,第一个式子中不能直接求出的 Fn,1 可以用第二个式子带入,得到:

[F1,m1][cd01]n1[ab01]m1=[Fn,11]

这个式子中不能直接求出的 F1,m 又可以带回第一个式子,得到:

[f1,11][ab01]2m2[cd01]n1=[Fn,11]

直接用矩阵快速幂即可。

对于输入而言,根据欧拉定理:

axaxmodϕ(p)(modp)

我们用字符串读入n,m ,然后直接对 ϕ(109+7)=109+6 取余即可。

注意 :在 a=1 时,原来作为底数的矩阵主对角线均为1,相当于数字1,此时欧拉定理不适用,不能模 ϕ(p) 而应当模 p

#include<cstdio>
#include<cstring>
#include<iomanip>
using namespace std;
typedef long long ll;
const ll phi=1e9+6,N=1e6+50,MOD=1e9+7;
struct Matrix{
ll a[3][3];
Matrix(){memset(a,0,sizeof(a));}
Matrix operator *(const Matrix x){
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]=(ans.a[i][j]+a[i][k]*x.a[k][j]%MOD)%MOD;
}
}
}
return ans;
}
}A1,A2,A3;
char nn[N],mm[N];
ll a,b,c,d,n,m;
void Pre()//字符串转化为数字
{
int lenn=strlen(nn+1);
int lenm=strlen(mm+1);
ll pow=1;
for(int i=lenn;i>=1;i--){
n=(n+pow*(nn[i]-48));
pow*=10;
if(a==1) n%=MOD,pow%=MOD;//特判底数矩阵为1的情况
else n%=phi,pow%=phi;
}
pow=1;
for(int i=lenm;i>=1;i--){
m=(m+pow*(mm[i]-48));
pow*=10;
if(a==1) m%=MOD,pow%=MOD;
else m%=phi,pow%=phi;
}
}
Matrix FastPow(Matrix x,ll b)//矩阵快速幂
{
Matrix ans;
ans.a[1][1]=ans.a[2][2]=1;
while(b){
if(b&1) ans=ans*x;
x=x*x;
b>>=1;
}
return ans;
}
int main()
{
scanf("%s%s",nn+1,mm+1);
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
Pre();
A1.a[1][1]=A1.a[1][2]=1;
A2.a[1][1]=a,A2.a[1][2]=0,A2.a[2][1]=b,A2.a[2][2]=1;
A3.a[1][1]=c,A3.a[1][2]=0,A3.a[2][1]=d,A3.a[2][2]=1;
//赋初值
Matrix x=FastPow(A2,(2*m-1)%phi);
Matrix tmp=FastPow(A2,(m-1)%phi)*A3;
Matrix ans=A1*FastPow(tmp,(n-1)%phi)*FastPow(A2,(m-1)%phi);
printf("%lld\n",ans.a[1][1]%MOD);
return 0;
}

本文作者:lxzy

本文链接:https://www.cnblogs.com/Unlimited-Chan/p/16448266.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   lxzy  阅读(41)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.