又是测数据的一天?不知情的我又爆零了。
T2.树的解构(deconstruct)
题目大意:给定(1)为根,随机选择一条边删去,删去的代价为这条边所指向的子节点的子树大小,求删去(n-1)条边时的期望。
因为整棵子树计算会有子孙节点是否被删除过,所以我们可以只计算当前这个点的贡献,而不是这棵子树的。
对于当前节点肯定只有到根节点的路径上的边有贡献,所以其余边的方案数为(C_{n-1}^{dep_u} imes (n-dep_u-1)!),然后计算贡献就从一棵树变成了一条链。
我们现在来考虑一条链的情况,因为我们要计算贡献的点只是链的末尾,所以枚举贡献的多少,然后计算即可,要考虑我们计算的是所有方案的贡献,所以贡献还要乘以当前的方案数,可证明为第二类斯特林数,递推公式为(f_i=f_{i-1}*i+(i-1)!),先预处理好,然后(O(n))计算即可。
手起码落,把这题咔嚓了:
#include<bits/stdc++.h>
#define re register
#define mod 1000000007
using namespace std;
inline int read()
{
re int x=0,f=1;
re char ch=getchar();
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f*=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
return x*f;
}
const int N=2000005;
inline long long Pow(long long x,int y)
{
re long long sum=1;
for(;y;y>>=1,x=x*x%mod)
if(y&1) sum=sum*x%mod;
return sum;
}
struct edge{int v,net;}e[N];
int n,cnt,hd[N],dep[N];
long long ans,jc[N]={1},inv[N]={1},f[N];
queue <int> q;
inline void add(int u,int v){e[++cnt].v=v,e[cnt].net=hd[u],hd[u]=cnt;}
void first()
{
q.push(1);
for(re int u;!q.empty();q.pop())
{
u=q.front();
for(re int i=hd[u],v;i;i=e[i].net)
{
v=e[i].v;
dep[v]=dep[u]+1;
q.push(v);
}
}
}
inline long long C(int m,int n){return jc[m]*inv[n]%mod*inv[m-n]%mod;}
int main()
{
freopen("deconstruct.in","r",stdin);
freopen("deconstruct.out","w",stdout);
scanf("%d",&n);
for(re int i=1;i<=n;i++) jc[i]=jc[i-1]*i%mod,inv[i]=Pow(jc[i],mod-2);
for(re int i=2;i<=n;i++) add(read(),i);
f[1]=1;for(re int i=1;i<=n;i++) f[i]=(f[i-1]*i+jc[i-1])%mod;
first();
for(re int i=1;i<=n;i++)
ans=(ans+C(n-1,dep[i])*jc[n-dep[i]-1]%mod*f[dep[i]]%mod)%mod;
printf("%lld",ans*inv[n-1]%mod);
return 0;
}
T3.小T与灵石(stone)
题目大意:一棵(n)个结点的有根树,树的根为(1)。一共有(q)次操作,第(i)次操作选定(k_i)个点(p_1),(p_2),...,(p_{k_i}),对每个点(x)定义(f_{x,i}=max^{k_i}_{j=1})(dist(x,pj)),其中(dist(x,y))表示树上(x),(y)两点间最短路经过的边数。再对每个点(x)定义(g_x=min^{q}_{i=1}(f_x,i)),对于每个点你需要求出(g_x)。
题目可以简化一下,大概可以想得出是在给出的点的直径上乱搞,因为要找的时最长的路径,所以一定是直径上的端点作为路径上的端点,又因为要找更长的那一个,所以我们只要找所有点到直径的中点就行了,然后再加上直径长度的一半就行
要注意的是,可能会出现中点在边上的情况,这是我们就可以建一个虚点,但要注意,虚点与其他点计算长度为(frac{1}{2})(卡在这好久),然后换根DP就行了。
悲惨,代码就不放了,(dalao)们应该,不肯定能很快写完的!