• 洛谷 P4451 [国家集训队]整数的lqp拆分


    题意简述

    (F_{x})为斐波那契数列第(x)
    将一个数(n)拆分为(a{1}, a{2}, ..., a{m}), 即(a{1} + a{2} +...+ a{m} = n)
    求(sumprodlimits_{i =1}^m F_{a_i})

    题解思路

    递推
    (g(i))为当n = i时的答案
    所以
    (g(i) = sumlimits_{j = 1} ^ {i - 1} g(j) * F_{i - j} + F_i)
    (g(i + 1) = sumlimits_{j = 1} ^ {i} g(j) * F_{i + 1 - j} + F_{i + 1})
    (g(i + 1) - g(i))
    $ = sumlimits_{j = 1} ^ {i - 1} g(j) * (F_{i + 1 - j} - F_{i - j}) + g(i) * F_1 + F_{i + 1} - F_i( ) = sumlimits_{j = 1} ^ {i - 1} g(j) * F_{i - j - 1} + g(i) + F_{i - 1}( ) = sumlimits_{j = 1} ^ {i - 2} g(j) * F_{i - j - 1} + F_{i - 1} + g(i)( ) = g(i - 1) + g(i)$
    所以 (g(i + 1) = 2 * g(i) + g(i - 1))(g(0) = 0, g(1) = 1)
    再直接递推或矩阵快速幂求第(n)项即可

    代码

    #include <cstdio>
    typedef long long ll;
    const int mod = 1000000007;
    int T, N;
    int n;
    struct Matrix
    {
        int a[4][4];
        Matrix& operator =(const Matrix& x)
        {
            for (register int i = 1; i <= N; ++i)
                for (register int j = 1; j <= N; ++j)
                    a[i][j] = x.a[i][j];
            return *this;
        }
    };
    Matrix a, b, c;
    Matrix Mul(const Matrix& x, const Matrix& y)
    {
        Matrix s;
        for (register int i = 1; i <= N; ++i)
            for (register int j = 1; j <= N; ++j)
                s.a[i][j] = 0;
        for (register int k = 1; k <= N; ++k)
        	for (register int i = 1; i <= N; ++i)
            	for (register int j = 1; j <= N; ++j)
                    s.a[i][j] = (s.a[i][j] + (ll)x.a[i][k] * y.a[k][j] % mod) % mod;
        return s;
    }
    Matrix _pow(Matrix x, int y)
    {
        Matrix s;
        for (register int i = 1; i <= N; ++i)
            for (register int j = 1; j <= N; ++j)
                s.a[i][j] = (i == j);
        for (; y; y >>= 1, x = Mul(x, x)) if (y & 1) s = Mul(s, x);
        return s;
    }
    int main()
    {
        N = 2;
        scanf("%d", &n);
        c.a[1][1] = 0; c.a[1][2] = 1;
        a.a[2][1] = a.a[1][2] = 1; a.a[2][2] = 2;
        if (n <= 1) {printf("%d
    ", c.a[1][n + 1]); return 0; }
        b = Mul(c, _pow(a, n - 1));
        printf("%d
    ", b.a[1][2]);
    }
    
  • 相关阅读:
    vue 实现返回上一页不请求数据keep-alive
    vue+webpack 实现懒加载的三种方式
    深度解析使用CSS单位px、em、rem、vh、vw、vmin、vmax实现页面布局
    vue2.0中 怎么引用less?
    vue 自定义 提示框(Toast)组件
    Flex 布局教程实例
    Vue.js经典开源项目汇总
    Vue插件编写、用法详解(附demo)
    vue 项目 使用sass以及注意事项
    vue2.0+vue-video-player实现hls播放的案例
  • 原文地址:https://www.cnblogs.com/xuyixuan/p/9898042.html
Copyright © 2020-2023  润新知