思路
设F(x)的第x项系数为权值和为x的答案
题目中要求权值必须在集合中出现,这个不好处理,考虑再设一个C,C的第x项如果是1代表x出现在值域里,如果是0,代表x没有出现在值域里,然后由于二叉树可以分别对左右子树处理,所以\[ F_k=\sum_{i=1}^k C_i \sum_{j=0}^{k-i}F_j F_{k-i-j} \]
\[ F_0=1 \]
可以看出这是一个卷积的形式
\[ F=1+C*F*F \]
然后解一个一元二次方程
\[ F=\frac{1 \pm \sqrt{1-4C}}{2C}=\frac{2}{1 \pm \sqrt{1-4C}} \]
因为\(C_0=0\),\(F_0=1\),所以去掉负号
然后上多项式求逆和多项式开方即可
代码
#include#include #include #define int long longusing namespace std;const int MAXN = 300000;const int MOD = 998244353;const int G = 3;const int invG = 332748118;struct Poly{ int t,data[MAXN]; Poly(){};};int pow(int a,int b){ int ans=1; while(b){ if(b&1) ans=(1LL*ans*a)%MOD; a=(1LL*a*a)%MOD; b>>=1; } return ans;}void NTT(Poly &a,int opt,int n){ int lim=0; while((1<<(lim)) >j)&1) t|=(1<<(lim-j-1)); if(i >1,midlen); static Poly tmp; while((dep<<1)>midlen) midlen<<=1; for(int i=0;i >1); while((dep<<1)>(midlen)) midlen<<=1; static Poly tmp1,tmp2,tmp3; tmp1=b;tmp3=b; save(tmp1,dep-1); save(tmp2,-1); save(tmp3,dep-1); int midlent=1; for(int i=0;i