HAOI2018苹果树

题解

首先所有生成树的情况树是\(n!\)的,因为第一次有1中方法,第二次有两种放法,以此类推。。。

然后我们发现距离这种东西可以直接枚举每条边算贡献。

于是我们枚举了一个点\(i\),又枚举了这个点的子树大小\(size\),那么这部分的距离也就可以直接算出来了。
\[
(n-size)*size
\]
接下来我们还要去算有多少种方案。

对于子树内部,标号和排列方法都没有确定,所以方案数就是:
\[
\binom{n-i}{size}*size!
\]
然后考虑子树外的情况,首先子树外的点不可能放到子树内去废话,那么第一次只可能有\((i-2+1)\)种方法,第二次就是\((i+1-2+1)\)种,以此类推,最后我们还要考虑前\(i\)个点的生成方式,可以知道是\(n!\)种。

所以最后就是:
\[
size*(n-size)*\binom{n-i}{size-1}*size!*\biggl(\prod_{k=i-1}^{n-j-1}k\biggr)*i!
\]

代码

#include<bits/stdc++.h>
#define N 2009
using namespace std;
typedef long long ll;
const int maxn=2000;
int n,mod;
ll ans,jie[N],c[N][N],d[N][N];
inline void MOD(ll &x){x=x>=mod?x-mod:x;}
inline void MOD(int &x){x=x>=mod?x-mod:x;}
inline ll rd(){
    ll x=0;char c=getchar();bool f=0;
    while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return f?-x:x;
}
int main(){
    n=rd();mod=rd();
    c[0][0]=1;
    for(int i=1;i<=maxn;++i){
        c[i][0]=1;
        for(int j=1;j<=i;++j)MOD(c[i][j]=c[i-1][j]+c[i-1][j-1]);
    }
    jie[0]=1;
    for(int i=1;i<=maxn;++i)jie[i]=jie[i-1]*i%mod;
    for(int i=1;i<=maxn;++i){
        for(int j=0;j<=maxn;++j)d[i][j]=1;
        d[i][i]=i;
        for(int j=i+1;j<=maxn;++j)d[i][j]=d[i][j-1]*j%mod;
    }
    for(int i=2;i<=n;++i)
      for(int j=1;j<=n-i+1;++j)MOD(ans+=1ll*j*(n-j)%mod*c[n-i][j-1]%mod*jie[j]%mod*d[i-1][n-j-1]%mod*jie[i]%mod);
    cout<<ans;
    return 0;
}
 

原文地址:https://www.cnblogs.com/ZH-comld/p/10778096.html

时间: 2024-08-30 18:36:30

HAOI2018苹果树的相关文章

[HAOI2018]苹果树

题目描述 小 C 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支. 经过细心的观察, 小 C 发现每一天这棵树都会生长出一个新的结点. 第一天的时候, 果树会长出一个根结点, 以后每一天, 果树会随机选择一个当前树中没有长出过结点 的分支, 然后在这个分支上长出一个新结点, 新结点与分支所属的结点之间连接上一条边. 小 C 定义一棵果树的不便度为树上两两结点之间的距离之和, 两个结点之间 的距离定义为从一个点走到另一个点的路径经过的边数. 现在他非常好奇, 如果 NNN 天之后小

Luogu 4492 [HAOI2018]苹果树 组合数

https://www.luogu.org/problemnew/show/P4492 找每个编号的点的父边的贡献,组合数和阶乘就能算了. 我考场上怎么就是没想到呢. 调了好久好久好久好久调不出来,样例一直过不了,刚刚发现是溢出了,我是个zz. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<iostream> 6

bzoj 5305 [Haoi2018] 苹果树

传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=5305 [题解] 1 # include <bits/stdc++.h> 2 using namespace std; 3 4 const int M = 2010; 5 6 int n, mod; 7 int C[M][M], fac[M]; 8 9 int main() { 10 cin >> n >> mod; 11 fac[0] = 1; 12 for (

HAOI2018 简要题解

这套题是 dy, wearry 出的.学长好强啊,可惜都 \(wc\) 退役了.. 话说 wearry 真的是一个计数神仙..就没看到他计不出来的题...每次考他模拟赛总有一两道毒瘤计数TAT 上午的官方题解可以看 dy0607 的博客,写的挺详细的. 「HAOI2018」奇怪的背包 题意 小C非常擅长背包问题,他有一个奇怪的背包,这个背包有一个参数 \(P\) ,当他向这个背包内放入若干个物品后,背包的重量是物品总体积对 \(P\) 取模后的结果. 现在小C有 \(n\) 种体积不同的物品,第

codevs——1228 苹果树

1228 苹果树 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结出很多的苹果.卡卡非常喜欢吃苹果,所以他一直都精心的呵护这棵苹果树.我们知道树是有很多分叉点的,苹果会长在枝条的分叉点上面,且不会有两个苹果结在一起.卡卡很想知道一个分叉点所代表的子树上所结的苹果的数目,以便研究苹果树哪些枝条的结果能力比较强. 卡卡所知道的是,每隔一些时间,某些分叉点

苹果树(线段树+Dfs序)

1228 苹果树 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结出很多的苹果.卡卡非常喜欢吃苹果,所以他一直都精心的呵护这棵苹果树.我们知道树是有很多分叉点的,苹果会长在枝条的分叉点上面,且不会有两个苹果结在一起.卡卡很想知道一个分叉点所代表的子树上所结的苹果的数目,以便研究苹果树哪些枝条的结果能力比较强. 卡卡所知道的是,每隔一些时间,某些分叉点上会结出一些苹果,但

[Codevs] 1228 苹果树

1228 苹果树 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结出很多的苹果.卡卡非常喜欢吃苹果,所以他一直都精心的呵护这棵苹果树.我们知道树是有很多分叉点的,苹果会长在枝条的分叉点上面,且不会有两个苹果结在一起.卡卡很想知道一个分叉点所代表的子树上所结的苹果的数目,以便研究苹果树哪些枝条的结果能力比较强. 卡卡所知道的是,每隔一些时间,某些分叉点上会结出一些苹果,但

Bzoj3757 苹果树

Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1978  Solved: 550 Description 神犇家门口种了一棵苹果树.苹果树作为一棵树,当然是呈树状结构,每根树枝连接两个苹果,每个苹果都可以沿着一条由树枝构成的路径连到树根,而且这样的路径只存在一条.由于这棵苹果树是神犇种的,所以苹果都发生了变异,变成了各种各样的颜色.我们用一个到n之间的正整数来表示一种颜色.树上一共有n个苹果.每个苹果都被编了号码,号码为一个1到n之间的正整数.我

二叉苹果树(树型DP+背包)

二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点).这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树: 2   5 \  / 3  4 \  / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 程序名:apple 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=