zoukankan      html  css  js  c++  java
  • NOI2013 矩阵游戏 【数论】

    题目描述

    婷婷是个喜欢矩阵的小朋友,有一天她想用电脑生成一个巨大的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的余数。

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    3 4 1 3 2 6
    
    输出样例#1:
    85
    

    说明

    【样例1说明】

    样例中的矩阵为:

    1 4 7 10

    26 29 32 35

    76 79 82 85

    数据范围



    题解

    我们从f[n][m]往前推导,最终可以推出:
    x = a^(m - 1) * c
    y = a^(m - 1) * d
    p = b * (a^(m - 1) - 1) / (a - 1)
    q = (x^(n - 1) - 1) / (x - 1)
    则结果为
    ans = x^(n - 1) * (a^(m - 1) + p) + (y + p) * q;

    由于指数非常大,我们运用费马小定理a^(p - 1) ≡ 1 (mod p)
    a^(m - 1) ≡ a^((m - 1) mod (p - 1)) (mod p)

    还有p,q的实质与等比数列有关,若公比为1,要特判一下
    然后就A了~~

    通过这题加深了对费马小定理的理解

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    using namespace std;
    const int maxn = 100005,maxm = 100005,INF = 2000000000;
    const LL P = 1000000007;
    
    void getread(LL& out,LL& out2){
    	char c = getchar();
    	out = out2 = 0;
    	LL mod = P - 1;
    	while (c < 48 || c > 57) c = getchar();
    	while (c >= 48 && c <= 57){
    		out = out * 10 + c - '0';
    		out2 = out2 * 10 + c - '0';
    		out %= mod;
    		out2 %= P;
    		c = getchar();
    	}
    	out = (out - 1 + mod) % mod;
    	out2 = (out2 - 1 + P) % P;
    }
    
    inline LL qpow(LL a,LL b){
    	int ans = 1;
    	for (; b; b >>= 1,a = a * a %P)
    		if (b & 1)
    			ans = ans * a % P;
    	return ans;
    }
    
    int main(){
    	LL n_1,m_1,n,m,a,b,c,d,p,q,x,y;
    	getread(n_1,n);
    	getread(m_1,m);
    	cin>>a>>b>>c>>d;
    	LL am_1 = qpow(a,m_1);
    	if (a == 1) p = b * m % P;
    	else p = b * (am_1 - 1) % P * qpow(a - 1,P - 2) % P;
    	x = am_1 * c % P;
    	y = am_1 * d % P;
    	if (x == 1) q = n;
    	else q = (qpow(x,n_1) - 1 + P) % P * qpow(x - 1,P - 2) % P;
    	LL ans = ((qpow(x,n_1) * ((am_1 + p) % P) % P + (y + p) % P * q % P) % P + P) % P;
    	cout<<ans<<endl;
    	return 0;
    }
    






  • 相关阅读:
    mysql:添加索引
    mysql: update字段中带select
    ASP.NET Web API 2 入门
    notify()、notifyAll()和wait()
    Mybatis3 框架理解
    项目中用到的Java注解
    使用webservice实现App与服务器端数据交互
    IntelliJ idea 14 集成 tomcat 7
    使用adb签名并安装Android程序
    写了一个月的单元测试,总算明白大学里这门课白学了
  • 原文地址:https://www.cnblogs.com/Mychael/p/8282859.html
Copyright © 2011-2022 走看看