zoukankan      html  css  js  c++  java
  • Luogu P1939矩阵加速

    Description:

    a[1]=a[2]=a[3]=1
    a[x]=a[x-3]+a[x-1] (x>3)
    求a数列的第n项对1000000007(10^9+7)取余的值。

    Analysis:

    [left[ egin{matrix} a_x \ a_{x-1}\a_{x-2} end{matrix} ight] = left[ egin{matrix} 1 & 0 & 1\ 1 & 0 & 0\0 & 1 & 0 end{matrix} ight] cdot left[ egin{matrix} a_{x-1} \ a_{x-2}\a_{x-3} end{matrix} ight] ]

    Code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define ll long long
    const int mod = 1000000007;
    using namespace std;
    int n,T; 
    struct Matrix{
    	ll data[10][10];
    	int r,c;
    	Matrix(int R,int C)
    	{
    		r = R;
    		c = C;
    		memset(data,0,sizeof(data));
    	}
    	ll* operator [](int pos)
    	{
    		return data[pos];	
    	}
    	Matrix operator *(Matrix B)
    	{
    		Matrix C(r,B.c);
    		for(int i = 1;i <= r;++i){
    			for(int j = 1;j <= B.c;++j){
    				for(int k = 1;k <= c;++k){
    					C[i][j] = (C[i][j]%mod + (data[i][k]%mod)*(B[k][j]%mod)%mod)%mod;
    				}
    			}
    		}
    		return C;
    	}
    Matrix operator *(int b){
            Matrix B(R,C);
            for(int i = 1;i <= R;++i){
                for(int j = 1;j <= C;++j){
                    B[i][j] = data[i][j]*b;
                }
            }
            return B;
        }
        Matrix T(){
            Matrix B(C,R);
            for(int i = 1;i <= C;++i){
                for(int j = 1;j <= R;++j){
                    B[i][j] = data[j][i];
                }
            }
            return B;
        }
    	void print(){
    		for(int i = 1;i <= r;++i)
    		{
    			for(int j = 1;j <= c;++j)
    			{
    				printf("%lld ",data[i][j]);
    			}
    			puts("");
    		}
    	}
    };
    Matrix Pow(Matrix A,int b){
    	Matrix res(A.r,A.c);
    	for(int i = 1;i <= A.r;++i) res[i][i] = 1;//单位矩阵,相当于整数乘法中的1
    	for(;b;b >>= 1){
    		if(b&1) res = res*A;
    		A = A*A;
    	}
    	return res;
    }
    int main()
    {
    	scanf("%d",&T);
    	for(int i = 1;i <= T;++i){
    		scanf("%d",&n);
    		Matrix A(3,3);
    		A[1][1] = A[1][3] = A[2][1] = A[3][2] = 1;
    		if(n <= 3){
    			printf("1
    ");
    		} else {
    			A = Pow(A,n-3);
    			printf("%lld
    ",(A[1][1]%mod + A[1][2]%mod + A[1][3]%mod)%mod);
    		}
    	}
    	return 0;
    }
    
    
    岂能尽如人意,但求无愧我心
  • 相关阅读:
    C嵌入汇编
    App 运营 推广相关
    POJ 3904 Sky Code
    数组的复制与动态扩展算法
    另类病毒的自删除方法
    oracle触发器中增删改查本表
    POJ 2773 Happy 2006 数学题
    Android手机便携式wifi的使用及无线数据传输(主要针对XP系统)
    Find the minimum线段树成段更新
    使用visual c++ 2005编译64位可执行文件
  • 原文地址:https://www.cnblogs.com/Zforw/p/10799157.html
Copyright © 2011-2022 走看看