hdu 3483 矩阵乘法

这个题目上周对抗赛题目,搞了我好久 对数学这种不是很敏感

其实都不是自己想出来的,看其他的资料和博客的推导 还是有点难度的,反正我是推不出来

通过二项式定理的化简

有两个博客写得比较好

http://972169909-qq-com.iteye.com/blog/1863402

http://www.cppblog.com/Yuan/archive/2010/08/13/123268.html

反正构造好二项式之后,乘N次,就可以得到结果了,因为右边的式子 初始全部是x。

#include <iostream>
#include <cstring>
#include <cstdio>
#define ll __int64
using namespace std;
const int maxn = 52;
ll c[maxn][maxn], a[maxn][maxn], b[maxn][maxn], t[maxn][maxn];
ll  N,x,M;
void init()
{
    int i, j;
    memset(c, 0, sizeof(c));
    for (i = 0; i <= x; i++)
    {
        c[i][0] = c[i][i] = 1;
        for (j = 1; j < i; j++)
        {
            c[i][j] = (c[i-1][j] + c[i-1][j-1]) % M;
        }
    }
    memset(a, 0, sizeof(a));
    for (i = 0; i <= x; i++)
    {
        for (j = 0; j <= i; j++)
        {
            a[i][j] = (c[i][j] * x) % M;
        }
    }
    memcpy(a[x+1], a[x], sizeof(a[x]));
    a[x+1][x+1] = 1;
    memset(b, 0, sizeof(b));
    for (i = 0; i <= x+1; i++)
    {
        b[i][i] = 1;
    }
}
void mul(long long p[maxn][maxn], long long q[maxn][maxn])
{
    int i, j, k;
    memset(t, 0, sizeof(t));
    for (i = 0; i <= x+1; i++)
    {
        for (j = 0; j <= x+1; j++)
        {
            for (k = 0; k <= x+1; k++)
            {
                t[i][j] = (t[i][j] + p[i][k] * q[k][j]) % M;
            }
        }
    }
    memcpy(q, t, sizeof(t));
}
void cal()
{
    while (N)
    {
        if (N & 1)
        {
            mul(a, b);
        }
        mul(a, a);
        N >>= 1;
    }
}
int main()
{
    while (scanf("%I64d %I64d %I64d", &N, &x,&M)&& N>0 && x>0 &&M>0)
    {
        init();
        cal();
        printf("%I64d
", b[x+1][0]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/kkrisen/p/3601803.html