题解:CF954H Path Counting
更好的阅读体验
这么简单的题哪里有 *2500 啊 /fn
一条路径的形态和两个端点的 LCA 有关。路径总共有两种情况:LCA 在端点上、LCA 不在端点上。
我们发现深度为
对于第二种情况,计算链长为
此时再设一端是 LCA 的
因此有:
把分母移出来,就变成:
直接做是
发现把求和符号展开后式子变成
可以
那么这道题就做完了,可以预处理前缀积和逆前缀积,复杂度为
#include<bits/stdc++.h>
#define endl '\n'
#define N 5006
#define MOD 1000000007
using namespace std;
int n,a[N],mul[N<<2],imul[N<<2],ans[N<<2],f[N<<1][N];
inline void add(int &x,int y){x+=y,x-=x>=MOD?MOD:0;}
int qpow(int x,int y)
{
if(y==0)return 1;if(y==1)return x%MOD;
int ret=qpow(x,y>>1);return 1ll*ret*ret%MOD*qpow(x,y&1)%MOD;
}
int binom2(int x){return (1ll*x*(x-1)/2)%MOD;}
main()
{
scanf("%d",&n),mul[0]=1;
for(int i=1;i<n;i++)
scanf("%d",&a[i]),mul[i]=1ll*mul[i-1]*a[i]%MOD;
imul[n-1]=qpow(mul[n-1],MOD-2);
for(int i=n-2;~i;i--)imul[i]=1ll*imul[i+1]*a[i+1]%MOD;
for(int t=1;t<=2*n-2;t++)
for(int i=1;i<n;i++)add(ans[t],mul[i+t-1]);
for(int i=n-1;i;i--)
{
f[2][i]=1ll*mul[i]*mul[i]%MOD;
for(int t=3;t<=2*n-2;t++)
f[t][i]=(f[t-2][i+1]+2ll*mul[i]*mul[i+t-2]%MOD)%MOD;
}
for(int t=1;t<=2*n-2;t++)
for(int i=1;i<n;i++)
add(ans[t],1ll*mul[i-1]*imul[i]%MOD*imul[i]%MOD*binom2(a[i])%MOD*f[t][i]%MOD);
for(int i=1;i<=2*n-2;i++)
printf("%d ",ans[i]);
return 0;
}