P1397 [NOI2013] 矩阵游戏(矩阵乘法&欧拉定理)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1397 [NOI2013] 矩阵游戏(矩阵乘法&欧拉定理)相关的知识,希望对你有一定的参考价值。
P1397 [NOI2013] 矩阵游戏(矩阵乘法&欧拉定理)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e6+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define db double
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr)
void Print(int *a,int n)
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
template <typename T> //x=max(x,y) x=min(x,y)
void cmx(T &x,T y)
if(x<y) x=y;
template <typename T>
void cmn(T &x,T y)
if(x>y) x=y;
struct mtx
ll a[3][3];
int r,c;
mtx(int rr,int cc,int p=0)
r=rr,c=cc;
mst(a,0);
if(p==1) for(int i=1;i<=rr;i++) a[i][i]=1;
mtx operator *(const mtx &b)const
mtx m(r,b.c);
for(int i=1;i<=r;i++)
for(int j=1;j<=m.c;j++)
for(int k=1;k<=c;k++)
m.a[i][j]=(m.a[i][j]+1LL*a[i][k]*b.a[k][j]%mod)%mod;
return m;
mtx operator ^(int n)const
mtx ans(r,c,1),x=*this;
while(n)
if(n&1) ans=ans*x;
x=x*x;
n>>=1;
return ans;
;
char s[N],t[N];
int n,m,a,b,c,d;
int main()
mtx A(2,2),B(2,2),C(2,2);
scanf("%s%s%d%d%d%d",s,t,&a,&b,&c,&d);
int l = strlen(s);
int mo = (a==1)?mod:mod-1;
for(int i=0;i<l;i++)
n = (n*10LL + (s[i]-'0')) %mo;
l = strlen(t);
for(int i=0;i<l;i++)
m = (m*10LL + (t[i]-'0')) %mo;
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;
A=A^(m-1);
C = A;
A=A*B;
A=A^(n-1);
A=A*C;
mtx D(1,2);
D.a[1][1] = D.a[1][2] = 1;
D=D*A;
printf("%d\\n",D.a[1][1]);
return 0;
上面的做法过不了UOJ的数据。
所以正解直接对大整数跑10进制的快速幂。
#include<bits/stdc++.h>
using namespace std;
const int N=1000005,P=1e9+7;
char n[N],m[N];int nl,ml,a,b,c,d;
struct detint d[2][2];I,p,q;
det operator*(det x,det y)
det r=;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
r.d[i][j]=(1ll*x.d[i][k]*y.d[k][j]+r.d[i][j])%P;
return r;
void pw(char*x,int l)
for(int i=l-1;~i;i--)
det k=p;
for(char j='0';j<x[i];j++)I=I*k;
for(int j=0;j<9;j++)p=p*k;
int main()
scanf("%s%s%d%d%d%d",n,m,&a,&b,&c,&d);
nl=strlen(n);
ml=strlen(m);
n[nl-1]--;
m[ml-1]--;
for(int i=nl-1;n[i]<'0';i--)
n[i]+=10,n[i-1]--;
for(int i=ml-1;m[i]<'0';i--)
m[i]+=10,m[i-1]--;
I.d[0][0]=1;
I.d[1][1]=1;
p.d[0][0]=a;
p.d[0][1]=b;
p.d[1][1]=1;
q.d[0][0]=c;
q.d[0][1]=d;
q.d[1][1]=1;
pw(m,ml);
p=q*I;
pw(n,nl);
cout<<(I.d[0][0]+I.d[0][1])%P;
return 0;
以上是关于P1397 [NOI2013] 矩阵游戏(矩阵乘法&欧拉定理)的主要内容,如果未能解决你的问题,请参考以下文章
bzoj3240 && 洛谷P1397矩阵游戏[NOI2013](矩阵乘法+卡常)