題目大意:求乙個滿足$k$階齊次線性遞推數列$a_i$的第$n$項。
即:$a_n=\sum\limits_^f_i \times a_$
題解:線性齊次遞推,先見洛谷題解,下回再補
卡點:陣列大小計算錯誤,求逆中途計算時忘記加$mod$等
c++ code:(這份全部是板子,可以用來測試,但是常數巨大)
#include #include #include #include #include #define maxk 32010#define maxn 131072
const int mod = 998244353;
#define mul(x, y) static_cast(x) * (y) % mod
namespace math
inline int inv(int x)
}inline void reduce(int &x)
namespace poly
inline void fft(int *a, const int op = 1)
} if (!op)
} void inv(int *a, int *b, int n)
static int c[n], d[n];
const int len = n + 1 >> 1;
inv(a, b, len), init(len * 3);
std::memcpy(c, a, n << 2), std::memset(c + n, 0, lim - n << 2);
std::memcpy(d, b, len << 2), std::memset(d + len, 0, lim - len << 2);
fft(c), fft(d);
for (int i = 0; i < lim; ++i) d[i] = (2 - mul(d[i], c[i]) + mod) * d[i] % mod;
fft(d, 0);
std::memcpy(b + len, d + len, n - len << 2);
} void div(int *a, int *b, int *q, int n, int m)
void div_mod(int *a, int *b, int *q, int *r, int n, int m)
void mod(int *a, int *b, int m)
void pow(int *base, int p, int *mod, int m)
p >>= 1;
if (p)
} std::memcpy(base, res, m << 2);
} int solve(int *f, int *a, int n, int k)
#undef n
}int n, k;
int f[maxk], a[maxk];
int main()
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
std::cin >> n >> k;
for (int i = 1; i <= k; ++i) std::cin >> f[i];
for (int i = 0; i < k; ++i) std::cin >> a[i], reduce(a[i]);
std::cout << poly::solve(f, a, n, k) << '\n';
return 0;
}
發現取模的那乙個多項式是一定的,可以預處理出它的逆元以及點值表示式等,減小常數。
c++ code:(這乙份常數還算正常)
#include #include #include #include #include #define maxk 32010#define maxn 65536
const int mod = 998244353;
#define mul(x, y) static_cast(x) * (y) % mod
namespace math
inline int inv(int x)
}inline void reduce(int &x)
namespace poly
inline void fft(int *a, const int op = 1)
} if (!op)
} void inv(int *a, int *b, int n)
static int c[n], d[n];
const int len = n + 1 >> 1;
inv(a, b, len), init(len * 3);
std::memcpy(c, a, n << 2), std::memset(c + n, 0, lim - n << 2);
std::memcpy(d, b, len << 2), std::memset(d + len, 0, lim - len << 2);
fft(c), fft(d);
for (int i = 0; i < lim; ++i) d[i] = (2 - mul(d[i], c[i]) + mod) * d[i] % mod;
fft(d, 0);
std::memcpy(b + len, d + len, n - len << 2);
} int g[n], invg[n];
void div(int *a, int *q, int n, int m)
void div_mod(int *a, int *r, int n, int m)
void pow(int *a, int p, int m)
div_mod(t, a, 2 * m, m + 1);
} int solve(int *f, int *a, int n, int k)
#undef n
}int n, k;
int f[maxk], a[maxk];
int main()
洛谷P4723 模板 線性遞推(多項式取模)
傳送門 考慮說要求乙個 a n i 1 kan if ia n sum a f i an i 1k an i fi 寫成矩陣的形式就是 a n an 1 f a0 fn a n a f a 0f n an an 1 f a0 fn實際上f nf n fn最後就是乙個長度為k kk的向量 滿足a n ...
洛谷 P3811 模板 乘法逆元 線性遞推逆元
給出n,p,求1 n所有數模p意義下的逆元.無論是擴充套件歐幾里得還是費馬小定理都是o n log 的,會t,這題因為是求1 n的所有數的逆元,因而可以遞推,若要求inv i 則可以設k p i,b p i.那麼k i b p 則k i b與0同餘.所以k i與 b同餘.所以k inv b 與 in...
洛谷 P3812 模板 線性基
這是一道模板題。給定n個整數 數字可能重複 求在這些數中選取任意個,使得他們的異或和最大。第一行乙個數n,表示元素個數 接下來一行n個數 僅一行,表示答案。輸入 1 2 1 1輸出 1 11 n 50,0 si 250 1 leq n leq 50,0 leq s i leq 2 1 n 50,0 ...