Fibonacci Harmony ("Copa HKUST IFLYTEK" Concurso preliminar de diseño del programa 17 de la Universidad de Tongji y Partido amistoso J de College Network, Matrix Fast Power)

1. Enlace de título:

Suma de Fibonacci

2. La idea principal del tema:

mendicidad  \ sum _ {i = 1} ^ {n} i ^ kfib (i), \; \;  1 \ leq n \ leq 10 ^ {18}, 1 \ leq k \ leq 100

3. Análisis:

Durante el juego, Du Jiao BM mantuvo wa, pero después del juego, descubrí que el módulo estaba mal ...

Dado que Dujiao BM puede ser AC colocando directamente la plantilla y cambiando el módulo, aquí solo se proporcionan soluciones que no son de Dujiao BM (¿a Dujiao BM no le gusta?

Primero haz una explicación del símbolo

F_k (n) = \ sum _ {i = 1} ^ ni ^ kfib (i)

G_k (n) = \ sum _ {i = 1} ^ {n} (n - i) ^ k fib (i)

 Después de la simbolización, se requiere el título F_k (n)

Luego encuentra  F_k (n) la fórmula de recursividad

G_k (n) = \ sum_ {i = 1} ^ n (n - i) ^ k fib (i)

G_k (n) = \ sum_ {i = 1} ^ n ((-i) + n) ^ k fib (i)

G_k (n) = \ sum_ {i = 1} ^ n \ sum_ {j = 0} ^ k \ binom {k} {j} (-i) ^ jn ^ {kj} fib (i)

G_k (n) = \ sum_ {i = 1} ^ n \ sum_ {j = 0} ^ k \ binom {k} {j} (-1) ^ ji ^ jn ^ {kj} fib (i)

G_k (n) = \ sum_ {j = 0} ^ k \ binom {k} {j} (-1) ^ jn ^ {kj} \ sum_ {i = 1} ^ ni ^ j fib (i)

G_k (n) = \ sum_ {j = 0} ^ k \ binom {k} {j} (-1) ^ jn ^ {kj} F_j (n)

G_k (n) = (-1) ^ kF_k (n) + \ sum_ {j = 0} ^ {k-1} \ binom {k} {j} (-1) ^ jn ^ {kj} F_j (n)

(-1) ^ kF_k (n) = G_k (n) - \ sum_ {j = 0} ^ {k-1} \ binom {k} {j} (-1) ^ jn ^ {kj} F_j (n)

Al calcular  F_k (n) , F_j (n) se han calculado los valores anteriores  , por lo que solo necesitamos Ginebra), \; \;  0 \ leq i \ leq k

Buscando la siguiente  G_k (n) fórmula de recursividad

Cuando  k = 0 el tiempo

G_0 (n) = \ sum_ {i = 1} ^ {n} fib (i) = fib (i + 2) - 1

Cuando  k \ geq 1 el tiempo

G_k (n + 1) - G_k (n) = \ sum _ {i = 1} ^ {n + 1} (n + 1- i) ^ kfib (i) - \ sum _ {i = 1} ^ {n } (n - i) ^ kfib (i)

G_k (n + 1) - G_k (n) = \ sum _ {i = 1} ^ {n} (n + 1- i) ^ kfib (i) - \ sum _ {i = 1} ^ {n} ( n - i) ^ kfib (i)

G_k (n + 1) - G_k (n) = \ sum _ {i = 1} ^ {n} ((n + 1- i) ^ k - (n - i) ^ k) fib (i)

G_k (n + 1) - G_k (n) = \ sum _ {i = 1} ^ {n} (((n - i) +1) ^ k - (n - i) ^ k) fib (i)

G_k (n + 1) - G_k (n) = \ sum _ {i = 1} ^ {n} (\ sum_ {j = 0} ^ {k} \ binom {k} {j} (ni) ^ j - (n - i) ^ k) fib (i)

G_k (n + 1) - G_k (n) = \ sum _ {i = 1} ^ {n} \ sum_ {j = 0} ^ {k-1} \ binom {k} {j} (ni) ^ jfib (yo)

G_k (n + 1) - G_k (n) = \ sum_ {j = 0} ^ {k-1} \ binom {k} {j} \ sum _ {i = 1} ^ {n} (ni) ^ jfib (yo)

G_k (n + 1) - G_k (n) = \ sum_ {j = 0} ^ {k-1} \ binom {k} {j} G_j (n)

G_k (n + 1) = G_k (n) + \ sum_ {j = 0} ^ {k-1} \ binom {k} {j} G_j (n)

G_k (n + 1) = \ sum_ {j = 0} ^ {k} \ binom {k} {j} G_j (n)

En este punto podemos usar la matriz para resolver rápidamente la potencia Ginebra), \; \;  0 \ leq i \ leq k

Específicamente

 G = \ left [\ begin {matrix} G_k (n) & G_ {k-1} (n) & \ cdots & G_0 (n) & fib (n + 2) & fib (n + 1) & 1 \\ 0 & 0 & \ cdots & 0 & 0 & 0 & 0 \\ \ vdots & \ vdots & \ cdots & \ vdots & \ vdots & \ vdots & \ vdots \\ 0 & 0 & \ cdots & 0 & 0 & 0 & 0 \ end {matriz} \ right] _ {k + 4}

G '= \ left [\ begin {matrix} G_k (n-1) & G_ {k-1} (n-1) & \ cdots & G_0 (n-1) & fib (n + 1) & fib (n ) & 1 \\ 0 & 0 & \ cdots & 0 & 0 & 0 & 0 \\ \ vdots & \ vdots & \ cdots & \ vdots & \ vdots & \ vdots & \ vdots \\ 0 & 0 & \ cdots & 0 & 0 & 0 & 0 \ end {matrix} \ right] _ {k + 4}

B = \ left [\ begin {matrix} \ binom {k} {k} & 0 & 0 & 0 & \ cdots & 0 & 0 & 0 & 0 & 0 \\ \ binom {k} {k-1} & \ binom {k-1} {k-1} & 0 & 0 & \ cdots & 0 & 0 & 0 & 0 & 0 \\ \ binom {k} {k-2} & \ binom {k-1} { k-2} & \ binom {k-2} {k-2} & 0 & \ cdots & 0 & 0 & 0 & 0 & 0 \\ \ vdots & \ vdots & \ vdots & \ vdots & \ vdots & \ vdots & \ vdots & \ vdots & \ vdots & \ vdots \\ \ binom {k} {1} & \ binom {k-1} {1} & \ binom {k-2} {1} & \ binom {k- 3} {1} & \ cdots & \ binom {1} {1} & 0 & 0 & 0 & 0 \\ \ binom {k} {0} & \ binom {k-1} {0} & \ binom { k-2} {0} & \ binom {k-3} {0} & \ cdots & \ binom {1} {0} & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & \ cdots & 0 & 1 & 1 & 1 & 0 \\ 0 &0 & 0 & 0 & \ cdots & 0 & 1 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & \ cdots & 0 & -1 & 0 & 0 & 1 \ end {matrix} \ right] _ {k + 4}

Conocible G = G'B

A = \ left [\ begin {matrix} 0 & 0 & \ cdots & 1 & 2 & 1 & 1 \\ 0 & 0 & \ cdots & 0 & 0 & 0 & 0 \\ \ vdots & \ vdots & \ cdots & \ vdots & \ vdots & \ vdots & \ vdots \\ 0 & 0 & \ cdots & 0 & 0 & 0 & 0 \ end {matrix} \ right] _ {k + 4}

El cálculo recursivo sabe G = AB ^ {n-1}

4. Implementación del código:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int M = (int)1e2 + 4;
const ll mod = (ll)998244353;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;

ll n; int k;
ll g[M + 5];
ll f[M + 5];

struct node
{
    ll D[M + 5][M + 5];
};

ll quick(ll a, ll b)
{
    ll sum = 1;
    while(b)
    {
        if(b & 1) sum = sum * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return (sum + mod) % mod;
}

node mul(node a, node b)
{
    node c; memset(c.D, 0, sizeof(c.D));
    for(int i = 0; i < M; ++i)
    for(int j = 0; j < M; ++j)
    for(int l = 0; l < M; ++l)
    c.D[i][j] = (c.D[i][j] + a.D[i][l] * b.D[l][j] % mod) % mod;
    return c;
}

node quick(node a, ll b)
{
    node sum; memset(sum.D, 0, sizeof(sum.D));
    for(int i = 0; i < M; ++i) sum.D[i][i] = 1;
    while(b)
    {
        if(b & 1) sum = mul(sum, a);
        a = mul(a, a);
        b >>= 1;
    }
    return sum;
}

int main()
{
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    scanf("%lld %d", &n, &k);
    node A, B;
    memset(A.D, 0, sizeof(A.D));
    memset(B.D, 0, sizeof(B.D));
    A.D[0][k] = 1, A.D[0][k + 1] = 2, A.D[0][k + 2] = 1, A.D[0][k + 3] = 1;
    for(int j = k; j >= 0; --j)
    {
        B.D[k][j] = 1;
        for(int i = k - 1; i >= j; --i) B.D[i][j] = (B.D[i][j + 1] + B.D[i + 1][j + 1]) % mod;
    }
    B.D[k][k] = 0;
    B.D[k + 1][k] = B.D[k + 1][k + 1] = B.D[k + 1][k + 2] = 1;
    B.D[k + 2][k] = B.D[k + 2][k + 1] = 1;
    B.D[k + 3][k] = -1, B.D[k + 3][k + 3] = 1;
    node G = mul(A, quick(B, n - 1));
    for(int i = 0; i <= k; ++i) g[i] = G.D[0][k - i];
    f[0] = G.D[0][k + 1] - 1;
    for(int i = 1; i <= k; ++i)
    {
        f[i] = g[i];
        for(int j = 0; j <= i - 1; ++j) f[i] = (f[i] + (((j&1)<<1)-1) * B.D[k - j][k - i] * quick(n % mod, i - j) % mod * f[j] % mod) % mod;
        if(i & 1) f[i] *= -1;
        f[i] = (f[i] + mod) % mod;
    }
    printf("%lld\n", f[k]);
    return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/The___Flash/article/details/106066577
Recomendado
Clasificación