标签:倍增 mat static play memset because 2-2 假设 迭代
想了想还是分开来发好了
求 \(B\) 满足 \(AB \equiv 1 \pmod{x^{2n}}\)
假设已经求出 \(B_0\) 满足 \(AB_0 \equiv 1 \pmod{x^n}\)
\(\because B -B_0\equiv 0 \pmod{x^n}\)
\(\therefore B^2-2BB_0+B_0^2\equiv 0 \pmod{x^{2n}}\)
$\therefore B-2B_0+AB_0^2\equiv 0 \pmod{x^{2n}} $
\(\therefore B\equiv 2B_0-AB_0^2\pmod{x^{2n}}\)
倍增即可
复杂度 \(T(N)=T(N/2)+O(NlogN)=O(NlogN)\)
代码(我的是迭代实现的)
inline void calc_inv(int n, int *a, int *b){
b[0] = fpow(a[0]);
static int c[N];
for(int u = 2, k = 4; u <= n; u <<= 1, k <<= 1){
memcpy(c, a, u << 2), memset(c + u, 0, u << 2);
get_rev(k);
ntt(c, k, 1), ntt(b, k, 1);
REP(i, 0, k - 1)b[i] = (2ll - 1ll * c[i] * b[i] % P + P) % P * b[i] % P;
ntt(b, k, -1), memset(b + u, 0, u << 2);
}
}
不过这样复杂度的确是对了,但是常数不小
咋优化?
还考虑这个式子 \(B\equiv 2B_0-B_0AB_0\pmod{x^{2n}}\)
设 \(C=AB_0\equiv 1 \pmod{x^n}\)
\[
[x^{t}]B=2[x^{t}]B_0-\sum_{k=0}^{t}[x^k]B_0\times[x^{t-k}]C=[x^t]B_0-\sum_{k=0}^{t-1}[x^k]B_0\times [x^{t-k}]C
\]
NTT的规模会减半(原来要两倍长度)
inline void calc_inv(int n, int *a, int *b){
b[0] = fpow(a[0]);
static int c[N], d[N];
for(int u = 1, k = 2; k <= n; u <<= 1, k <<= 1){
memcpy(c, a, k << 2), memcpy(d, b, u << 2), memset(b + u, 0, u << 2);
get_rev(k), ntt(b, k, 1), ntt(c, k, 1);
REP(i, 0, k - 1)c[i] = 1ll * c[i] * b[i] % P;
ntt(c, k, -1);
memset(c, 0, u << 2);
REP(i, u, k)c[i] = P - c[i];
ntt(c, k, 1);
REP(i, 0, k - 1)b[i] = 1ll * b[i] * c[i] % P;
ntt(b, k, -1);
memcpy(b, d, u << 2);
}
}
标签:倍增 mat static play memset because 2-2 假设 迭代
原文地址:https://www.cnblogs.com/HolyK/p/10262412.html