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的余数。

    数据范围

    分析

    初始矩阵(A_3)

    [A_3= left[ egin{matrix} 1\ 1 end{matrix} ight] ]

    列转移矩阵(A_1)

    [A_1= left[ egin{matrix} a & b\ 0 & 1 end{matrix} ight] ]

    行转移矩阵(A_2)

    [A_2= left[ egin{matrix} c & d\ 0 & 1 end{matrix} ight] ]

    转移到最后一行,最后一列,应该是

    [A_1^{m-1}(A_2A_1^{m-1})^{n-1}A_3 ]

    代码

    n,m是十进制大数,需要十进制快速幂。

    此题还有数学分析做法,矩阵的做法卡常数,需要O3才能过

    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<ctime>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<list>
    #include<deque>
    #include<stack>
    #include<queue>
    #include<map>
    #include<set>
    #include<bitset>
    #include<algorithm>
    #include<complex>
    #define il inline
    #define rg register
    #pragma GCC optimize ("O3")
    using namespace std;
    template<class T> inline T read(T&x)
    {
        T data=0;
    	int w=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
        while(isdigit(ch))
            data=10*data+ch-'0',ch=getchar();
        return x=data*w;
    }
    typedef long long ll;
    const int INF=0x7fffffff;
    
    const int mod=1e9+7;
    
    struct Matrix
    {
    	int data[2][2];
    	
    	il Matrix()
    	{
    		memset(data,0,sizeof(data));
    	}
    	
    	il int*operator[](rg const int&x)
    	{
    		return data[x];
    	}
    	
    	il Matrix operator*(rg const Matrix&rhs)
    	{
    		rg Matrix res;
    		for(rg int i=0;i<2;++i)
    			for(rg int j=0;j<2;++j)
    				for(rg int k=0;k<2;++k)
    				{
    					res[i][j] += (ll)data[i][k] * rhs.data[k][j] % mod;
    					if(res[i][j] >= mod)
    						res[i][j] -= mod;
    				}
    		return res;
    	}
    	
    	il Matrix&operator*=(rg const Matrix&rhs)
    	{
    		return *this=*this*rhs;
    	}
    }A1,A2,A3;
    
    il Matrix spow(rg Matrix x,rg int k)
    {
    	rg Matrix res;
    	for(rg int i=0;i<2;++i)
    		res[i][i]=1;
    	while(k)
    	{
    		if(k&1)
    			res*=x;
    		x*=x,k>>=1;
    	}
    	return res;
    }
    
    il Matrix bpow(rg Matrix x,rg char*k)
    {
    	rg Matrix res;
    	for(rg int i=0;i<2;++i)
    		res[i][i]=1;
    	rg int len=strlen(k+1);
    	for(rg int i=len;i;--i)
    	{
    		res *= spow(x,k[i]-'0');
    		x = spow(x,10);
    	}
    	return res;
    }
    
    const int MAXN=1e6+7;
    char n[MAXN],m[MAXN];
    int a,b,c,d;
    
    int main()
    {
    //  freopen(".in","r",stdin);
    //  freopen(".out","w",stdout);
    	scanf("%s %s",n+1,m+1);
    	read(a);read(b);read(c);read(d);
    	int nl=strlen(n+1),ml=strlen(m+1);
    	for(rg int i=nl;i;--i)
    	{
    		if(n[i]=='0')
    			n[i]='9';
    		else
    		{
    			n[i]--;
    			break;
    		}
    	}
    	for(rg int i=ml;i;--i)
    	{
    		if(m[i]=='0')
    			m[i]='9';
    		else
    		{
    			m[i]--;
    			break;
    		}
    	}
    	A1[0][0]=a,A1[0][1]=b,A1[1][1]=1;
    	A1=bpow(A1,m);
    	A2[0][0]=c,A2[0][1]=d,A2[1][1]=1;
    	A2*=A1,A2=A1*bpow(A2,n);
    	printf("%d
    ",(A2[0][0]+A2[0][1])%mod);
    //  fclose(stdin);
    //  fclose(stdout);
        return 0;
    }
    
    静渊以有谋,疏通而知事。
  • 相关阅读:
    Using Project Custom Properties to replace all end point of test cases
    Jacoco Code coverage with Robotframework Maven pom.xml example
    Jacoco Code coverage with Robotframework
    Test coverage in a multi module Maven project
    如何让linux的history命令显示时间记录
    项目角色职责分配表
    Linux检查哪些thread在占用CPU
    soapui_mockservicerunner_script.sh
    Some api interface link of Soapui
    GlusterFS分布式存储系统
  • 原文地址:https://www.cnblogs.com/autoint/p/9766727.html
Copyright © 2011-2022 走看看