• [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

    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 eq 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 eq 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;
    }
    
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    模糊化控制
    第8章 控制对象的访问(setter、getter、proxy)
    第7章 面向对象与原型
    Termux键盘配置
    在md里画流程图
    设置浏览器不缓存文件
    安卓手机使用Termux及搭建FTP服务器
    第6章 未来的函数:生成器和promise
    第5章 精通函数:闭包和作用域
    第4章 函数进阶:理解函数调用
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9373125.html
Copyright © 2020-2023  润新知