hdu4990Reading comprehension 矩阵快速幂

//a[0] = 0 
//a[n] = a[n-1] + n%2
//给n , 求a[n]
//a[n] = a[n-1] + (n+1)/2 - n/2
//构造矩阵
// |a[n]   | |2 1 -1 0| |a[n-1] |
// |(n+2)/2| |0 0  1 1| |(n+1)/2|
// |(n+1)/2| |0 1  0 0| |  n/2  |
// |   1   | |0 0  0 1| |   1   |
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
typedef long long ll ;
struct node
{
    ll p[10][10] ;
};
node mul(node a , node b , ll mod)
{
    node c ;
    memset(c.p , 0 , sizeof(c.p)) ;
    for(int i = 1;i <= 4;i++)
      for(int j = 1;j <= 4;j++)
        for(int k = 1;k <= 4;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 <= 4;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 , m ;
    while(~scanf("%lld%lld" , &n , &m))
    {
        node a ;
        memset(a.p , 0 ,sizeof(a.p)) ;
        a.p[1][1] = 2 ;
        a.p[1][2] = 1 ;
        a.p[1][3] = -1 ;
        a.p[2][3] = 1 ;
        a.p[2][4] = 1 ;
        a.p[3][2] = 1 ;
        a.p[4][4] = 1 ;
        node c = pow(a , n, m) ;
        printf("%lld\n" , ((c.p[1][4] + c.p[1][2])%m + m)%m) ;
    }
    return  0 ;
}




你可能感兴趣的:(hdu4990Reading comprehension 矩阵快速幂)