A. 组合
设 (f[x][i]) 为叉的下长减上长为 (i) 的方案,(g[x][i]) 为距离其长度为 (i) 的点数
直接转移是 (Theta(n^2)) 的,使用长链剖分进行优化
长链剖分将重儿子的定义改为最长链的儿子,一个性质是树上所有长链的总和为 (n)
转移的时候每个长链的儿子显然可以继承父亲的信息,另一个令人耳目一新的操作是使用数组分配下标的方式:先开一个长度为 (2n) 的数组,每次 (f,g) 直接分配,儿子的数组 f[son[x]]=f[x]+1,g[son[x]]=g[x]+1
剩下的都是 (dp) 的转移了:
For(j,0,len[t]-1){
ans+=g[t][j]*f[x][j+1]+f[t][j+1]*g[x][j];
if(j) f[x][j-1]+=f[t][j];
}For(j,0,len[t]-1) f[x][j+1]+=g[t][j]*g[x][j+1],g[x][j+1]+=g[t][j];
B.计数
除掉 (111dots1) 不好做,把 (N) 先乘九然后等比数列求和,所以得到一个 (sum_i frac{N}{10^{ik}})
也就是把 (N) 右移若干位,右移每一位的方案数可以调和级数算出来,其实这个是个减法卷积
NTT(f,lim,-1); NTT(G,lim,1);
Mul(F,G,Ans); NTT(Ans,lim,1);
但是这个东西还有一些余数,也就是每一位平移之后剩下的余数
精确计算很复杂,但是可以近似一些位(30位)来计算
具体实现可以考虑维护每一位向下 (30) 位的答案,对于 (le 10^{30}) 的余数,暴力维护每 (30) 位的答案,剩下的隔着跳一下
并不会证明为啥是 (30) 位的误差
C.排列
前置:最小树形图,朱刘算法
定义就是有向图给定根的最小生成树(即保证图联通)
思想就是找到有向图上所有的最小环,用外面的边迭代替换得到
考虑本题如果 (a_{p_i}) 选择 (b_{p_j}) 等价从 (p_j) 向 (p_i) 连了一个有向边
因为图没有根,那么建一个虚根就可以找到最小答案
对于最小字典序枚举每个位置填啥,然后把无关的边毙掉,只从虚根到这个点的答案的边