ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Day 11.25模拟赛游记

2020-11-25 22:01:23  阅读:195  来源: 互联网

标签:dep cnt ch int 11.25 re 游记 Day mod


又是测数据的一天?不知情的我又爆零了。


T2.树的解构(deconstruct)

题目大意:给定\(1\)为根,随机选择一条边删去,删去的代价为这条边所指向的子节点的子树大小,求删去\(n-1\)条边时的期望。

因为整棵子树计算会有子孙节点是否被删除过,所以我们可以只计算当前这个点的贡献,而不是这棵子树的。

对于当前节点肯定只有到根节点的路径上的边有贡献,所以其余边的方案数为\(C_{n-1}^{dep_u}\times (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\)们应该,不肯定能很快写完的!

标签:dep,cnt,ch,int,11.25,re,游记,Day,mod
来源: https://www.cnblogs.com/jkzcr01-QAQ/p/14039117.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有