zoukankan      html  css  js  c++  java
  • Day 11.25模拟赛游记

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


    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)们应该,不肯定能很快写完的!

  • 相关阅读:
    Django的中间件
    Django的Models(三)
    多个SSH key对应多个Host: Github, Bitbucket
    最简单的私有库方法
    Swift compile slow 编译慢问题
    Hide Xcode8 strange log.
    cocoapods 终极方案
    "Mac OS X"想要进行更改。键入管理员的名称和密码以允许执行此操作("Mac OS X"想使用系统钥匙串)
    Xcode7下载地址
    Xcode8安装不成功, 需要升级系统. The operation couldn't be completed. cpio read error
  • 原文地址:https://www.cnblogs.com/jkzcr01-QAQ/p/14039117.html
Copyright © 2011-2022 走看看