FFT
FFT
h>
正整数的有序拆分问题
生成函数 A(x)=x+x^2+...=x/(1-x);
则序列有 B(x)=1+A+A^2+...=1/(1-A),所以 B(x)=1+x/(1-2x)=1+x+2x^2+4x^3+...;
已知多项式 f(x),可以在 O(nlogn)求出 1/f(x)模 x^n 意义下(条件是 f(x)的常数项存在逆元)
已知 f(x),求 ln f(x)
设 g(x)=ln f(x),g'(x)=f'(x)/f(x),则 f(x)=f'(x)/g'(x);
n 个点连通图方案数
n 个点的图的生成函数 G(x)=∑2^c(i,2)x^i/i!;
n 个点连通图生成函数为 C(x)=∑Cix^i/i!;
G(x)=e^C(x),则 C(x)=ln(G(x));
已知 f(x),求 e^f(x) 牛顿迭代法 o(nlogn)
已知 f(x),求 f(x)^k mod x^n,
1.倍增快速幂的方法,O(nlognlogk)
2.f(x)^k=exp(ln(f(x)^k))=exp(kln(f(x))).(注意要将 f(x)常数项为 1,得求出逆元)
自己写的 fft,常数巨大
#include<bits/stdc++.h>
return v;
}
void init_eps(int n)
{
tot = n;
long long base = power(3, (mod_v - 1) / n);
long long inv_base = power(base, mod_v - 2);
eps[0] = 1, inv_eps[0] = 1;
for(int i = 1; i < n; ++i)
{
eps[i] = eps[i - 1] * base % mod_v;
inv_eps[i] = inv_eps[i - 1] * inv_base % mod_v;
}
}
void polynomial_inverse(int deg, long long* a, long long* b, long long* tmp)
{
if(deg == 1)
{
b[0] = power(a[0], mod_v - 2);
} else {
polynomial_inverse((deg + 1) >> 1, a, b, tmp);
int p = 1;
while(p < deg << 1) p <<= 1;
copy(a, a + deg, tmp);
fill(tmp + deg, tmp + p, 0);
transform(p, tmp, eps);
transform(p, b, eps);
for(int i = 0; i != p; ++i)
{
b[i] = (2 - tmp[i] * b[i] % mod_v) * b[i] % mod_v;
if(b[i] < 0) b[i] += mod_v;
}
transform(p, b, inv_eps);
long long inv = power(p, mod_v - 2);
for(int i = 0; i != p; ++i)
b[i] = b[i] * inv % mod_v;
fill(b + deg, b + p, 0);
}
}
int main()
{
init_eps(2048);
std::cout<<mod_v<<std::endl;
int n;
std::cin >> n;
for(int i = 0; i != n; ++i)
std::cin >> a[i];
polynomial_inverse(n, a, b, c);
std::cout << "inverse: ";
for(int i = 0; i != n; ++i)
printf("%lld ", (b[i] + mod_v) % mod_v);
std::cout << std::endl;
return 0;
}