NOI2013 矩阵游戏
题目链接:戳我
\[f[n][m]=a*f[n][m-1]+b
\]
\[=a^{m-1}*f[n][1]+b+ab+...+a^{m-2}b
\]
\[=a^{m-1}*(c*f[i-1][m]+d)+b+ab+...+a^{m-2}b
\]
\[=a^{m-1}*c*f[i-1][m]+a^{m-1}*d+b+ab+...+a^{m-2}b
\]
设\(a^{m-1}*c\)为\(x\)
\(b+ab+...+a^{m-2}b\)为\(p\)
设\(a^{m-1}*d+p\)为\(y\)
设\(y+xy+...+x^{n-2}y\)为q
设\(n,m\)是对\(mod-1\)取模的次数项\(n-1\),\(m-1\)
设\(nn,mm\)是对\(mod\)取模的系数项\(n-1\),\(m-1\)
\[f[n][m]=(x^n)(a^m)+q
\]
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAXN 100010
#define MOD 1000000007
using namespace std;
int n,m,a,b,c,d,nn,mm;
long long p,q,x,y;
inline int fpow(int x,int y,int mod)
{
int cur_ans=1;
while(y)
{
if(y&1) cur_ans=1ll*x*cur_ans%mod;
x=1ll*x*x%mod;
y>>=1;
}
return cur_ans%mod;
}
inline int inv(int x){return fpow(x,MOD-2,MOD);}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
int f=1;
char ch;
while(ch<'0'||ch>'9'){if(ch==-1)f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')
{
n=(10ll*n+ch-'0')%(MOD-1);
nn=(10ll*nn+ch-'0')%MOD;
ch=getchar();
}
n=(n+MOD-2)%(MOD-1);//次数n-1
nn=(nn+MOD-1)%MOD;//系数n-1
while(ch<'0'||ch>'9'){if(ch==-1)f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')
{
m=(10ll*m+ch-'0')%(MOD-1);
mm=(10ll*mm+ch-'0')%MOD;
ch=getchar();
}
m=(m+MOD-2)%(MOD-1);//次数m-1
mm=(mm+MOD-1)%MOD;//系数m-1
scanf("%d%d%d%d",&a,&b,&c,&d);
int am=fpow(a,m,MOD);
x=1ll*am*c%MOD;
if(a==1) p=1ll*b*mm%MOD;
else p=1ll*b*(1+MOD-am)%MOD*inv(1+MOD-a)%MOD;
int xn=fpow(x,n,MOD);
y=(1ll*am*d%MOD+p)%MOD;
if(x==1) q=1ll*y*nn%MOD;
else q=1ll*y*(1+MOD-xn)%MOD*inv(1+MOD-x)%MOD;
printf("%lld\n",(1ll*xn*(am+p)+q)%MOD);
return 0;
}