HDU 3493 The Little Architect【矩阵快速幂

33 篇文章 0 订阅

The Little Architect

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 235    Accepted Submission(s): 131


Problem Description
  LY is a little architect, he likes to make all kinds of buildings with his building blocks. All the building blocks are the same cubes. Now he want to make a new building. He don’t want any floor of his building is disconnected. So sample of the building he likes and he dislikes like these:


The building he likes. The building he dislikes.

  For example, the first building he likes because all the blocks in every line are not disconnected, while the second building he dislikes because in line 1, 3, 4, the blocks are disconnected.
  Now LY has a question. If he has n building blocks, and how many different buildings he can build. We ensure that all the building blocks are in the same plane.



 

Input
  There are several lines in the input. Each line is a set of input data. There is only one integer n (0 < n < 1,000,000,000) means the number of blocks buildings he has. The last line of the input is a line contains 0.
 

Output
  For each set of input, output a single line contains one integer which is the number of different buildings he can build mod 9997.
 

Sample Input
  
  
1 2 3 4 20 0
 

Sample Output
  
  
1 2 6 19 2840
Hint
When n = 3, there are 6 different buildings like these:
 

Source
 


#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<climits>
#include<string>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
#define rep(i,j,k)for(i=j;i<k;i++)
#define per(i,j,k)for(i=j;i>k;i++)
#define MS(x,y)memset(x,y,sizeof(x))
const int INF= 0x7FFFFFFF;
typedef  long long  LL;
const int MAX = 3;

typedef struct
{
    int m[MAX][MAX];
} Matrix;

Matrix P = {5,-7,4,
            1,0,0,
            0,1,0,
           };

Matrix I = {1,0,0,
            0,1,0,
            0,0,1,
           };

Matrix matrixmul(Matrix a,Matrix b) 
{
    int i,j,k;
    Matrix c;
    for (i = 0 ; i < MAX; i++)
        for (j = 0; j < MAX; j++)
        {
            c.m[i][j] = 0;
            for (k = 0; k < MAX; k++)
                c.m[i][j] += (a.m[i][k] * b.m[k][j])%9997;
            c.m[i][j] %= 9997;
        }
    return c;
}

Matrix quickpow(long long n)
{
    Matrix m = P, b = I;
    while (n >= 1)
    {
        if (n & 1)
            b = matrixmul(b,m);
        n = n >> 1;
        m = matrixmul(m,m);
    }
    return b;
}

int main()
{
    Matrix re;
    int f[3] = {2,6,19};
    long long n;
    while (scanf("%I64d",&n) && n != 0)
    {
        if (n == 1)
            printf("1\n");
        else if (n <= 4)
            printf("%d\n",f[n-2]);
        else
        {
            re = quickpow(n - 4);
            printf("%d\n",(((re.m[0][0]*f[2])+ (re.m[0][1]*f[1]) + (re.m[0][2]*f[0])) %9997 + 9997) % 9997);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值