[luogu1397 NOI2013] 矩阵游戏 (数学)

[luogu1397 NOI2013] 矩阵游戏 (数学)

传送门

Description

婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的n行m列的矩阵(你不用担心她如何存储)。她生成的这个矩阵满足一个神奇的性质:若用F[i][j]来表示矩阵中第i行第j列的元素,则F[i][j]满足下面的递推式:

F[1][1]=1

F[i,j]=a*F[i][j-1]+b (j!=1)

F[i,1]=c*F[i-1][m]+d (i!=1)

递推式中a,b,c,d都是给定的常数。

现在婷婷想知道F[n][m]的值是多少,请你帮助她。由于最终结果可能很大,你只需要输出F[n][m]除以1,000,000,007的余数。

Input

输入文件matrix.in包含一行有六个整数n,m,a,b,c,d。意义如题所述。

Output

输出文件matrix.out包含一个整数,表示F[n][m]除以1,000,000,007的余数。

Sample Input

3 4 1 3 2 6

Sample Output

85

HINT

1393969-20180726170714897-1649858585.png

Solution

突然感觉数列求和没白学。。
首先考虑一行的最后一个的表达式
\(f(i)=f(i-1)*a+b\)
\(f(m)=f(1)+(m-1)*b (a = 1)\)
\(f(m)=a^{m-1}+\frac{a^{m-1}-1}{a-1}*b (a \neq 1)\)
然后我们再考虑f(i,1)和f(i+1,1)关系
\(f(i+1,1)=f(i,m)*c+d\)
\(f(m)=f(1)*c+(m-1)*b*c+d (a = 1)\)
\(f(m)=a^{m-1}*c+\frac{a^{m-1}-1}{a-1}*b*c+d (a \neq 1)\)
(其实就套上面的式子)
由于a,b,c,d均为常数,所以这两个式子通过简单的变形便会和最上面的式子一样
然后再次套公式就能算出来\(f(n+1,1)\)
所以\(f(n,m)=\frac{f(n+1,1)-d}{c}\)就求完了
PS:
矩阵也适用费马小定理~
f(n,m)=f(n % (mod-1),m % (mod-1))

Code

//By Menteur_Hxy
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
using namespace std;
typedef long long LL;

const int MOD=1000000007;
LL n1,n2,m1,m2,a,b,c,d,p,k,t; 
char s1[1000010],s2[1000010];

void init() {
    int len1=strlen(s1+1);
    F(i,1,len1) n1=(n1*10+s1[i]-48)%MOD,n2=(n2*10+s1[i]-48)%(MOD-1);
    int len2=strlen(s2+1);
    F(i,1,len2) m1=(m1*10+s2[i]-48)%MOD,m2=(m2*10+s2[i]-48)%(MOD-1);
}

LL qpow(LL a,LL b) {
    LL t=1;
    while(b) {
        if(b&1) t=t*a%MOD;
        a=a*a%MOD; b>>=1;
    }
    return t;
} 

LL inv(LL x) {return qpow(x,MOD-2);}

int main() {
    scanf("%s%s%lld%lld%lld%lld",s1+1,s2+1,&a,&b,&c,&d);
    init();
    if(a==1) b=((m1-1)*b%MOD*c+d)%MOD,a=c;
    else {
        k=b*inv(a-1)%MOD;
        t=qpow(a,m2-1);
        a=c*t%MOD;
        b=((t-1)*k%MOD*c+d)%MOD;
    }
    if(a==1) p=(1+n1*b)%MOD;
    else {
        k=b*inv(a-1)%MOD;
        t=qpow(a,n2);
        p=(t+(t-1)*k)%MOD;
    }
    printf("%lld",((p-d)*inv(c)%MOD+MOD)%MOD);
    return 0;
}
posted @ 2018-07-26 17:24 Menteur_Hxy 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值