zoukankan      html  css  js  c++  java
  • HDU 1757 A Simple Math Problem(矩阵快速幂)

    题目链接:戳我

    题目大意:

    一个函数 f(x)  当 x < 10 ,f(x) = x;

    当 x >= 10 时,f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);

    给 k 和 m,求 f(k) % m的值

    样例解释:

    解题思路:

    用矩阵快速幂,建立A 矩阵为 10 * 10的,如下

    0 1 0 0 0 0 0 0 0 0
    0 0 1 0 0 0 0 0 0 0
    0 0 0 1 0 0 0 0 0 0
    0 0 0 0 1 0 0 0 0 0
    0 0 0 0 0 1 0 0 0 0
    0 0 0 0 0 0 1 0 0 0
    0 0 0 0 0 0 0 1 0 0
    0 0 0 0 0 0 0 0 1 0
    0 0 0 0 0 0 0 0 0 1
    a[9] a[8] a[7] a[6] a[5] a[4] a[3] a[2] a[1] a[0] 其中a数组为上面公式所对应的a

    B矩阵为 10 * 1 的, 如下

    [0;1;2;3;4;5;6;7;8;9]

    故f(n) 为 An * B 所得矩阵的最后一个元素

    代码:

    //Author LJH
    //www.cnblogs.com/tenlee
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #define clc(a, b) memset(a, b, sizeof(a))
    using namespace std;
    
    const int inf = 0x3f;
    const int INF = 0x3f3f3f3f;
    const int maxn = 10;
    int k, m;
    
    void Init(int a[][maxn], int ans[][maxn])
    {
        for(int i = 0; i < 9; i++)
        {
            for(int j = 0; j < 10; j++)
            {
                a[i][j] = 0;
                if(j-1 == i)
                {
                    a[i][j] = 1;
                }
            }
        }
        
        for(int i = 0; i < maxn; i++)
        {
            for(int j = 0; j < maxn; j++)
            {
                if(i == j)
                    ans[i][j] = 1;
                else 
                    ans[i][j] = 0;
            }
        }
    }
    
    void matrix_mul(int a[][maxn], int b[][maxn])
    {
        int i, j, k;
        int tmp[maxn][maxn] = {0};
        for(i = 0; i < maxn; i++)
        {
            for(j = 0; j < maxn; j++)
            {
                for(k = 0; k < maxn; k++)
                {
                    tmp[i][j] = (tmp[i][j] + a[i][k] * b[k][j] % m) % m;
                }
            }
        }
        for(i = 0; i < maxn; i++)
        {
            for(j = 0; j < maxn; j++)
            {
                a[i][j] = tmp[i][j];
            }
        }
        /*for(int i = 0; i < maxn; i++)
        {
            for(int j = 0; j < maxn; j++)
                printf("b %d ", a[i][j]);
            puts("");
        }*/
    }
    
    int quickPow(int a[maxn][maxn], int b[maxn], int ans[maxn][maxn], int n)
    {
        /*for(int i = 0; i < maxn; i++)
        {
            for(int j = 0; j < maxn; j++)
                printf("%d ", a[i][j]);
            puts("");
        }*/
        while(n)
        {
            if(n & 1) matrix_mul(ans, a);
            matrix_mul(a, a);
            n >>= 1;
        }
        /*for(int i = 0; i < maxn; i++)
        {
            for(int j = 0; j < maxn; j++)
                printf("%d ", ans[i][j]);
            puts("");
        }*/
        
        int sum = 0;
        for(int i = 0; i < maxn; i++)
        {
            sum = (sum + i * ans[9][i]) % m;
        }
        return sum % m;
    }
    
    void func(int a[][maxn])
    {
        int d[50];
        for(int i = 0; i < 10; i++)
            d[i] = i;
        for(int i = 10; i <= k; i++)
        {
            d[i] = 0;
            for(int j = 0; j < 10; j++)
            {
                d[i] = (d[i] + a[9][j] * d[i-j-1] % m) % m;
            }
            printf("%d#%d ", i, d[i]);
        }
        puts("");
    }
    int main()
    {
        freopen("1.txt", "r", stdin);
        int a[maxn][maxn], b[maxn], ans[maxn][maxn];
        while(~scanf("%d %d
    ", &k, &m))
        {
            Init(a, ans);
            for(int i = 0; i < 10; i++)
            {
                scanf("%d", &a[9][9-i]);
            }
            //func(a);
            if(k >= 10)
                printf("%d
    ", quickPow(a, b, ans, k-9));
            else 
                printf("%d
    ", k%m);
        }
        return 0;
    }
    

      

  • 相关阅读:
    集合set
    字典
    元组
    列表
    for循环
    Windows调试2.异常产生详细流程
    双机环境搭建
    Windows调试1.WinDbg基本使用-异常基础知识
    PE基础7-HOOK练习
    PE基础6_远程线程注入-HOOK(消息-InLine-IAT)
  • 原文地址:https://www.cnblogs.com/tenlee/p/4662438.html
Copyright © 2011-2022 走看看