zoukankan      html  css  js  c++  java
  • hdu 3306 Another kind of Fibonacci(矩阵高速幂)

    Another kind of Fibonacci

                                                           Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
                                                                                      Total Submission(s): 1691    Accepted Submission(s): 660


    Problem Description
    As we all known , the Fibonacci series : F(0) = 1, F(1) = 1, F(N) = F(N - 1) + F(N - 2) (N >= 2).Now we define another kind of Fibonacci : A(0) = 1 , A(1) = 1 , A(N) = X * A(N - 1) + Y * A(N - 2) (N >= 2).And we want to Calculate S(N) , S(N) = A(0)2 +A(1)2+……+A(n)2.

     

    Input
    There are several test cases.
    Each test case will contain three integers , N, X , Y .
    N : 2<= N <= 231 – 1
    X : 2<= X <= 231– 1
    Y : 2<= Y <= 231 – 1
     

    Output
    For each test case , output the answer of S(n).If the answer is too big , divide it by 10007 and give me the reminder.
     

    Sample Input
    2 1 1 3 2 3
     

    Sample Output
    6 196
     

    主要是递推矩阵,然后矩阵高速幂:
    依据S(n)=S(n-1)+A(n)^2,A(n)^2=X^2*A(n-1)^2+Y^2*A(n-2)^2+2*X*Y*A(n-1)*A(n-2)。A(n)*A(n-1)=Y*A(n-1)*A(n-2)+X*A(n-1)^2,能够构造例如以下的矩阵。然后用二分矩阵的方法求解就可以。
    递推矩阵

    代码:
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int mod=10007;
    struct matrix
    {
        long long ma[5][5];
    };
    matrix multi(matrix x,matrix y)//矩阵相乘
    {
        matrix ans;
        memset(ans.ma,0,sizeof(ans.ma));
        for(int i=1;i<=4;i++)
        {
            for(int j=1;j<=4;j++)
            {
                if(x.ma[i][j])//稀疏矩阵优化
                for(int k=1;k<=4;k++)
                {
                    ans.ma[i][k]=(ans.ma[i][k]+(x.ma[i][j]*y.ma[j][k])%mod)%mod;
                }
            }
        }
        return ans;
    }
    matrix pow(matrix a,long long m)
    {
        matrix ans;
        for(int i=1;i<=4;i++)
        {
            for(int j=1;j<=4;j++)
            {
                if(i==j)
                ans.ma[i][j]=1;
                else
                ans.ma[i][j]=0;
            }
        }
        while(m)
        {
            if(m&1)
            ans=multi(ans,a);
            a=multi(a,a);
            m=m>>1;
        }
        return ans;
    }
    int main()
    {
        long long x,y,n;
        while(~scanf("%I64d%I64d%I64d",&n,&x,&y))
        {
            matrix a,b;
            memset(a.ma,0,sizeof(a.ma));
            memset(b.ma,0,sizeof(b.ma));
            a.ma[1][1]=1;
            a.ma[1][2]=1;
            a.ma[2][2]=(x*x)%mod;
            a.ma[2][3]=(y*y)%mod;
            a.ma[2][4]=(2*x*y)%mod;
            a.ma[3][2]=1;
            a.ma[4][2]=x;
            a.ma[4][4]=y;
            b.ma[1][1]=1;
            b.ma[2][1]=1;
            b.ma[3][1]=1;
            b.ma[4][1]=1;
            a=pow(a,n);
            a=multi(a,b);
            printf("%I64d
    ",a.ma[1][1]);
        }
        return 0;
    }
    


  • 相关阅读:
    C#线程并发执行的实例[转]
    Win7怎么用IIS发布网站系统 部署项目
    C#:用SqlBulkCopy来实现批量插入数据
    jQuery 中post 、get的同步问题
    网页配色颜色表(推荐)
    如何修改eclipse的默认字符集和修改中文乱码
    eclipse学习
    SpringMVC开发流程
    SpringMVC的请求
    SpringMVC的数据响应
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7028859.html
Copyright © 2011-2022 走看看