您的位置:首页 > 其它

hdu4291A Short problem 矩阵快速幂

2015-09-04 15:34 169 查看
//g[0] = 0;
//g[1] = 1
//g
 = 3*g[n-1]+g[n-2]
//求g(g(g(n))) 
//本地暴力搜出循环节 ,然后用矩阵快速幂做
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
typedef long long ll ;
const ll mod1 = 1000000007 ;
const ll mod2 = 222222224 ;
const ll mod3 = 183120 ;
const int maxn = 3;
struct node
{
    ll p[maxn][maxn] ;
};
node mul(node a , node b , ll mod)
{
    node c ;
    memset(c.p , 0 , sizeof(c.p)) ;
    for(int i = 1;i <= 2;i++)
      for(int j = 1;j <= 2;j++)
        for(int k = 1;k <= 2;k++)
        c.p[i][j] = (c.p[i][j] + a.p[i][k]*b.p[k][j])%mod ;
    return c ;
}
node pow(node a , ll k ,  ll mod)
{
    node c ;
    memset(c.p , 0 , sizeof(c.p)) ;
    for(int i = 1;i <= 2;i++)
    c.p[i][i] = 1;
    while(k)
    {
        if(k&1)c = mul(c , a , mod) ;
        a = mul(a , a , mod) ;
        k >>= 1 ;
    }
    return  c ;
}
int main()
{
    ll n ;
    while(~scanf("%lld" ,&n))
    {
        node a ;
        a.p[1][1] = 3 ;
        a.p[1][2] = 1 ;
        a.p[2][1] = 1 ;
        a.p[2][2] = 0 ;
        node ans ;
        if(n < 2)
        {
            printf("%lld\n" , n) ;
            continue ;
        }
        ans = pow(a , n-1 , mod3) ;
        if(ans.p[1][1] >= 2)
        ans = pow(a , ans.p[1][1] - 1 , mod2) ;
        if(ans.p[1][1] >= 2)
        ans = pow(a , ans.p[1][1] - 1 , mod1) ;
        printf("%lld\n" , ans.p[1][1]) ;
    }
    return  0  ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: