题目大意
有一棵$n$个节点$m$条边的仙人掌,定义一种合法的染色方案为,满足每条边的两端的节点颜色均不相同的方案,询问$q$次,每次给出一个可以使用的颜色数量$c$,求出合法方案数。
$n,q\leq 100000,m\leq 2*n-2$
时限$2s$。
题解
首先,考虑树的情况。
列一个朴素dp,设$f_i$为$i$节点确定为某一种颜色后,子树的合法方案数。
转移:$f_u=\prod_{v \in ch[u] }f_v*(c-1)$
然后就会发现这™就是个快速幂......
式子为: $ans=c*(c-1)^{n-1}$
然后考虑环的情况。
依旧先考虑朴素$d$
发现树边可以同上处理,同时对于每个环,新开一个dp。
首先,将大小为$size$的环断开成线段,其中一端为环的根。
然后,设$f[i][0/1]$表示考虑到环上顺/逆时针第$i$个点,且这个点与环根的颜色不同/相同的方案数。
于是有转移:
$f[i][0]=f[i][1]$
$f[i][1]=(c-1)f[i][0]+(c-2)f[i][1]$
然后,取$f[size][1]*\prod_{v \in ring}f_v$作为这个环环根的dp值即可~
咱们依旧想化成快速幂。
于是考虑建一棵圆方树,此时方点代表一个环。
可以发现,方点处的$f_i$只需要满足如下式子:
$$f_i=(\prod_{v \in ch[u]}f_v*(c-1))*\frac{f[size][1]}{(c-1)^{size}}$$
这样就可以融入正常的 $f$ 值计算中了~
于是可以发现,每个环相当于一个额外系数,形如$\frac{f[size][1]}{(c-1)^{size}}$的系数~
那么 $ans=c*(c-1)^{n-1}*\prod_{ring \in G}\frac{f[size][1]}{(c-1)^{size}}$
可以发现,$f[size][1]$可以矩阵快速幂,$(c-1)^{size}$可以快速幂,即单个大小的环的贡献可以$O(2^3*\log n)$算出。
然后,由于不同的环大小最多只有$O(\sqrt{n})$种,爆算每种大小的环的贡献即可。
复杂度$O(2^3q\sqrt{n}\log n)$。
然而,博主使用上面的方法交上去的程序只得了$90pts$,最后一个点要$13s$。
因为,矩阵快速幂太™慢了。
于是优化矩阵快速幂,推一推式子。下面用$f_i$代替$f[i][1]$。
归纳矩阵的转移式,有$f_i=(c-2)f_{i-1}+(c-1)f_{i-2}$。
考虑化成$f_i+\lambda f_{i-1}=a(f_{i-1}+\lambda f_{i-2})$的形式:
$$ f_i+\lambda f_{i-1} = (c-2+\lambda)(f_{i-1}+\lambda f_{i-2}) $$
$$ f_i = (c-2)f_{i-1}+\lambda(c-2+\lambda) f_{i-2} $$
$$ \lambda(c-2+\lambda) = c-1 $$
$$ \lambda^2+(c-2)\lambda-(c-1) = 0 $$
$$ \lambda = 1 或 1-c $$
显然$\lambda=1$更好算。
于是有
$$ f_i+ f_{i-1} = (c-1)(f_{i-1}+f_{i-2}) $$
令$s_i=f_i+f_{i-1}$,那么有$s_i=(c-1)s_{i-1}$。
由于$s_2=f_2+f_1=(c-1)+0=c-1$,那么$s_i=(c-1)^{n-1}$。
于是又有
$$f_i=s_i-f_{i-1}=-f_{i-1}+(c-1)^{n-1}$$
考虑化成$f_i+a^{n+k}=b(f_{i-1}+a^{n+k-1})$的等比数列形式。
那么有
$$ f_i = -f_{i-1}+(c-1)^{i-1} $$
$$ f_i + T = -(f_{i-1}+\frac{T}{c-1}) $$
$$ f_i = -f_{i-1}-\frac{T}{c-1}-T $$
$$ T + \frac{T}{c-1} = -(c-1)^{i-1} $$
$$ cT = -(c-1)^i $$
$$ T = -\frac{(c-1)^i}{c} $$
于是$f_i - \frac{(c-1)^i}{c} = -(f_{i-1}-\frac{(c-1)^{i-1}}{c})$。
又$f_1-\frac{c-1}{c} = 0 - \frac{c-1}{c} = - \frac{c-1}{c}$,于是有:
$$ f_i - \frac{(c-1)^i}{c} = -(f_{i-1}-\frac{(c-1)^{i-1}}{c}) $$
$$ f_i - \frac{(c-1)^i}{c} = (-1)^i\frac{c-1}{c} $$
$$ f_i = (-1)^i\frac{c-1}{c} + \frac{(c-1)^i}{c} $$
于是便不用矩阵了~
于是就可以过了~
代码:
#include