題目傳送門
給出 \(k,a_,f_\) ,存在:
\[\forall n>k\wedge n\in \mathbb,\exists a_n=\sum_^f_ka_
\]給出 \(n\) ,求出 \(a_n\) 。
\(n\le 10^9,k\le 32000\)
以下部分借鑑了 bjpers2 的題解
恭喜您!您獲得了 \(\theta(k^3\log n)\) 的時間複雜度以及 \(0\) 分的好成績!!!以下是正解。我們考慮從斐波拉契數列入手,我們發現一下事情,假設 \(n=5\),那麼我們可以得到:
\[f_5=f_3+f_4=2f_3+f_2=2f_1+3f_2
\]就直接展開就好了。(這裡的 \(f_i\) 指的是第 \(i\) 位斐波拉契數列,並不是上面轉移式裡面的值)
然後我們就發現這個過程其實就是 \(x^5\) 對 \(x^2-x-1\) 取模的過程。
乙個感性的解釋就是說,這個過程就相當於將乙個高次抵消,換成它的展開式。最後的結果肯定就是最後的 \(k\) 次多項式。
考慮拓展,然後你發現根據上面的感性解釋,其實它的係數就是
\[x^n\bmod-f_2x^-f_3x^-...-f_kx^0)}
\]然後你發現這個東西直接多項式快速冪即可。時間複雜度 \(\theta(k\log k\log n)\) 。
#include using namespace std;
#define sz(x) ((int)x.size())
#define int register int
#define mod 998244353
#define maxn 1000005
int mul (int a,int b)
int dec (int a,int b)
int add (int a,int b)
int qkpow (int a,int k)
int inv (int x)
typedef vector poly;
int w[maxn],rev[maxn];
void init_ntt ()
void ntt (poly &a,int lim,int type)
for (int i = 0;i < lim;++ i) a[i] = d[i] % mod;
if (type == -1)
#undef g
#undef gi
}poly operator + (poly a,poly b)
poly operator - (poly a,poly b)
poly operator * (poly a,int b)
poly operator * (poly a,poly b)
poly inv (poly a,int n)
b.resize (n);
return b;
}poly inv (poly a)
template inline void read (t &t)while (c >= '0' && c <= '9') t *= f;}
template inline void read (t &t,args&... args)
template inline void write (t x)if (x > 9) write (x / 10);putchar (x % 10 + '0');}
poly operator % (poly f,poly g)
poly qkpow (int b,poly c)
int n,k,f[maxn],a[maxn];
poly f,g,q;
signed main()
常係數齊次線性遞推
給定遞推式 f n a 1f a 2 f a k f 給定 f 0,f 1.f k 求 f n 先定義 f n 的特徵方程 c x x a 1 x a 2 x a x a k 由基本代數定理,c x 0 的解 稱為特徵根 有 k 個,設為 alpha 1 alpha 2.alpha k 有 f n ...
常係數齊次線性遞推
見洛谷模板題。有個數列 給出前 k 項,即 a 0,a 1,dots,a 對於後面的所有 a n 有 a n sum f ia f 給出。小學生 直接幹。初中生 矩陣乘法。現在設 a 為轉移矩陣。列向量 vec v a a dots,a 0 滿足 a vec v a a dots,a 1 我們要求 ...
線性常係數齊次遞推總結
本文為作者的一些理解,如有錯誤之處請指出。其實就是這樣乙個式子 a n alpha 1a alpha 2a alpha 3a alpha ka 因為它是線性的,沒有高次的項,而且次數都相等,沒有一些不是常數的奇怪函式夾在裡面 所以它叫這個名字 還有它的特徵方程是 x k alpha 1x alpha...