求有多少个二叉树使每个点权值均在给定集合C中而且权值和为
令 fs 表示总权值为s的合格二叉树个数。
于是有
另外还有
剩下的问题就是计算 F(x) 了。
多项式开方 多项式求逆。。
复杂度是 O(nlogn) 还是 O(nlog2n) 的呢。。
VFK神的题解好详细的啦。
http://codeforces.com/blog/entry/12513
还有前置技能
http://picks.logdown.com/posts/189620-the-inverse-element-of-polynomial
http://picks.logdown.com/posts/197262-polynomial-division
http://picks.logdown.com/posts/202388-square-root-of-polynomial
真的写了很久。。
#include
#include
#define FOR(i,j,k) for(i=j;i<=k;++i)
#define rep(i,j,k) for(i=j;i
#define gmod(i) (((i)%mod+mod)%mod)
const int N = 262144, mod = 998244353, inv2 = 499122177;
using namespace std;
typedef long long ll;
ll qpow(ll x, int y) {
ll z = 1;
for (; y; x = x * x % mod, y /= 2)
if (y & 1) z = z * x % mod;
return z;
}
namespace NTT {
int n, rev[N], inv_n, m = -1;
void init(int c) {
int k = -1, i;
if (m == c) return; else m = c;
for (n = 1; n <= m; n <<= 1) ++k;
inv_n = qpow(n, mod - 2);
rep(i,0,n) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << k);
}
void ntt(int *a, int f) {
int h, i, j;
rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[i]]);
for (h = 2; h <= n; h *= 2) {
int wn = qpow(3, (mod - 1) / h);
for (i = 0; i < n; i += h) {
int w = 1;
rep(j,0,h/2) {
int u = a[i + j], t = 1ll * a[i + j + h / 2] * w % mod;
a[i + j + h / 2] = (u - t + mod) % mod;
a[i + j] = (u + t) % mod;
w = 1ll * w * wn % mod;
}
}
}
if (f) {
rep(i,1,n/2) swap(a[i], a[n - i]);
rep(i,0,n) a[i] = 1ll * a[i] * inv_n % mod;
}
}
}
void inv(int *a, int *b, int n) {
static int t[N];
int i;
if (n == 1) { b[0] = qpow(a[0], mod - 2); return; }
inv(a, b, n / 2);
rep(i,0,n) t[i] = a[i]; rep(i,n,2*n) t[i] = 0;
NTT::init(n);
NTT::ntt(t, 0); NTT::ntt(b, 0);
rep(i,0,NTT::n) t[i] = (ll) b[i] * gmod(2ll - (ll) t[i] * b[i] % mod) % mod;
NTT::ntt(t, 1);
rep(i,0,n) b[i] = t[i]; rep(i,n,2*n) b[i] = 0;
}
void sqrt(int *a, int *b, int n) {
static int t[N], b1[N];
if (n == 1) { b[0] = 1; return; }
int i;
sqrt(a, b, n / 2);
rep(i,0,n) b1[i] = 0;
inv(b, b1, n);
rep(i,0,n) t[i] = a[i]; rep(i,n,2*n) t[i] = 0;
NTT::init(n);
NTT::ntt(t, 0), NTT::ntt(b, 0), NTT::ntt(b1, 0);
rep(i,0,NTT::n) t[i] = inv2 * ((b[i] + (ll) b1[i] * t[i] % mod) % mod) % mod;
NTT::ntt(t, 1);
rep(i,0,n) b[i] = t[i]; rep(i,n,2*n) b[i] = 0;
}
int main() {
static int c[N], sc[N], ic[N];
int i, x, n, m, l;
scanf("%d%d", &n, &m);
FOR(i,1,n) scanf("%d", &x), ++c[x];
c[0] = gmod(1 - c[0]);
FOR(i,1,m) c[i] = gmod(-4 * c[i]);
for (l = 1; l <= m; l <<= 1);
sqrt(c, sc, l);
(++sc[0]) %= mod;
inv(sc, ic, l);
FOR(i,0,m) ic[i] = 2ll * ic[i] % mod;
FOR(i,1,m) printf("%d\n", ic[i]);
return 0;
}
Our child likes computer science very much, especially he likes binary trees.
Consider the sequence of n distinct positive integers: c1, c2, …, cn. The child calls a vertex-weighted rooted binary tree good if and only if for every vertex v, the weight of v is in the set {c1, c2, …, cn}. Also our child thinks that the weight of a vertex-weighted tree is the sum of all vertices’ weights.
Given an integer m, can you for all s(1 ≤ s ≤ m) calculate the number of good vertex-weighted rooted binary trees with weight s? Please, check the samples for better understanding what trees are considered different.
We only want to know the answer modulo 998244353 (7 × 17 × 223 + 1, a prime number).
The first line contains two integers n, m ( 1 ≤ n ≤ 105;1 ≤ m ≤ 105 ). The second line contains n space-separated pairwise distinct integers c1, c2, ⋯, cn . ( 1 ≤ ci ≤ 105 ).
Print m lines, each line containing a single integer. The i-th line must contain the number of good vertex-weighted rooted binary trees whose weight exactly equal to i. Print the answers modulo 998244353 (7 × 17 × 223 + 1, a prime number).
2 3
1 2
1
3
9
3 10
9 4 3
0
0
1
1
0
2
4
2
6
15
5 10
13 10 6 4 15
0
0
0
1
0
1
0
2
0
5
In the first example, there are 9 good vertex-weighted rooted binary trees whose weight exactly equal to 3: