[HNOI2015]落忆枫音

链接 :

[HNOI2015]落忆枫音

首先 原图是一个DAG
生成树即为除了根节点以外每个节点随便选一条入边组成的
所以生成树数量 = 各个点入度乘积

新加入一条边 分三种情况
1.如果不成环 那么可以把它放在原来的DAG里计算
2.如果它的终点为1 那么忽略不计
3.如果它成环的话 假设其中一个环大小是size
那么答案就是 每个点随便选一个入边 - 这个环形成的情况
即 ind[1] * ind[2] * ind[3] * ... * ind[n] / (ind[a_(1)] * ind[a_(2)] * ... * ind[a_(size)])

所有的环加起来就是
随便选一个入边 - 第一个环形成 - 第二个环形成 - ...
由于无论哪个环都必须包括这条新加入的边
所以并不会有冲突 不必容斥

ps 在膜p意义下 除以x等于乘x ^ (p - 2) <- x膜p的逆元
还有一种筛逆元的方法
void Linear_Shaker()
{
int i;
for( inv[ 1 ] = 1, i = 2; i <= m + 1; i++ )
inv[ i ] = ( MOD - MOD / i ) * inv[ MOD % i ] % MOD;
}

dp方程
dp[ i ] = Σj, ( i 可以到达 j ) dp[ j ] × inv( ind[ i ] )

posted @ 2018-08-14 18:56  hjmmm  阅读(144)  评论(0编辑  收藏  举报