好像又是神仙dp。。。。gan了一早上

首先这是个计数类问题,上DP,

对于一个最小生成树,按照kruskal是一个个联通块,枚举边小到大合成的

假如当前边是树边,那么转移应该还是枚举两个块然后合并

假如不是树边那么就在所有联通块所有非树边中任选一条

两个相邻树边之间的非树边方案应该是P(所有联通块总边数-(当前枚举到那条边-1),r-l-1)

然而按照我现在的智商还是不会捉

%了题解发现一个非常强大的性质,就是对于一个整数的无序拆分很小,40只有37338

设f[zt],其中zt表示一个状态,由一些联通块的大小组成,总和为n

这样可以爆搜一波把所有无序拆分也就是状态弄出来,并给一个新编号

转移就是枚举两个联通块然后合并

若第i,j个合并

(新状态的方案)+=(这个状态的方案)*(两条树边之间其他边选择的方案)*(第i个联通块的大小)*(第j个联通块的大小)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;int n;
struct zhuangtai
{int u[50];friend bool operator >(zhuangtai z1,zhuangtai z2){if(z1.u[0]==z2.u[0]){for(int i=1;i<=z1.u[0];i++)if(z1.u[i]!=z2.u[i])return z1.u[i]>z2.u[i];}return z1.u[0]>z2.u[0];}friend bool operator <(zhuangtai z1,zhuangtai z2){if(z1.u[0]==z2.u[0]){for(int i=1;i<=z1.u[0];i++)if(z1.u[i]!=z2.u[i])return z1.u[i]<z2.u[i];}return z1.u[0]<z2.u[0];}int getsum(){int ret=0;for(int i=1;i<=u[0];i++)ret=(ret+(u[i]*(u[i]-1)/2)%mod)%mod;return ret;}
}mp[41000];int z,g[50];
bool cmp(zhuangtai z1,zhuangtai z2){return z1>z2;}
map<zhuangtai,int>id;//通过状态找编号
void dfs(int d,int last)//预处理拆分n的方案
{if(d==n){z++;for(int i=0;i<=g[0];i++)mp[z].u[i]=g[i];return ;}for(int i=last;i+d<=n;i++) {g[++g[0]]=i;dfs(i+d,i);g[g[0]--]=0;}
}LL quick_pow(LL A,LL p)
{LL ret=1;while(p!=0){if(p%2==1)ret=ret*A%mod;A=A*A%mod;p/=2;}return ret;
}
LL fac[110000],fac_inv[110000];
LL getP(int n,int m){return fac[n]*fac_inv[n-m]%mod;}zhuangtai t;int h[50];
int getnzt(int zt,int x,int y)
{memcpy(h,mp[zt].u,sizeof(h));int d=h[x]+h[y]; memset(t.u,0,sizeof(t.u));for(int i=1;i<=h[0];i++){if(i!=x&&i!=y){if(d!=-1&&h[i]>d)t.u[++t.u[0]]=d,d=-1;t.u[++t.u[0]]=h[i];}}if(d!=-1)t.u[++t.u[0]]=d;return id[t];
}
int a[50];LL f[41000];
int main()
{fac[0]=1,fac_inv[0]=1;for(int i=1;i<=100000;i++)fac[i]=fac[i-1]*i%mod,fac_inv[i]=quick_pow(fac[i],mod-2);scanf("%d",&n);for(int i=1;i<n;i++)scanf("%d",&a[i]);z=0;dfs(0,1);sort(mp+1,mp+z+1,cmp);for(int i=1;i<=z;i++)id[mp[i]]=i;memset(f,0,sizeof(f));f[1]=1;for(int zt=1;zt<=z;zt++)if(f[zt]>0){int e=n-mp[zt].u[0]+1;//轮到第几条边用来合并LL P=getP(mp[zt].getsum()-(a[e-1]),a[e]-a[e-1]-1);//两条树边中间其他边选择的方案数 for(int i=1;i<=mp[zt].u[0];i++)for(int j=i+1;j<=mp[zt].u[0];j++){int nzt=getnzt(zt,i,j);f[nzt]=(f[nzt]+f[zt]*P%mod*mp[zt].u[i]%mod*mp[zt].u[j]%mod)%mod;}}int rst=n*(n-1)/2-a[n-1];printf("%lld\n",f[z]*getP(rst,rst)%mod);return 0;
}

转载于:https://www.cnblogs.com/AKCqhzdy/p/9753580.html

NOI.AC #31. MST相关推荐

  1. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  2. NOI.AC#2007-light【根号分治】

    正题 题目链接:http://noi.ac/problem/2007 题目大意 nnn个格子排成一排,每个格子有一个0/10/10/1和一个颜色.开始每个格子都是000,qqq次操作取反一个颜色的所有 ...

  3. NOI.AC#2139-选择【斜率优化dp,树状数组】

    正题 题目链接:http://noi.ac/problem/2139 题目大意 给出nnn个数字的序列aia_iai​.然后选出一个不降子序列最大化子序列的aia_iai​和减去没有任何一个数被选中的 ...

  4. NOI.AC#2144-子串【SAM,倍增】

    正题 题目链接:http://noi.ac/problem/2144 题目大意 给出一个字符串sss和一个序列aaa.将字符串sss的所有本质不同子串降序排序后,求有多少个区间[l,r][l,r][l ...

  5. NOI.AC#2266-Bacteria【根号分治,倍增】

    正题 题目链接:http://noi.ac/problem/2266 题目大意 给出nnn个点的一棵树,有一些边上有中转站(边长度为222,中间有一个中转站),否则就是边长为111. mmm次询问一个 ...

  6. 野鸡NOI.AC模拟赛【2019.10.26】

    前言 截止至2019.10.2614:222019.10.26\ \ \ \ 14:222019.10.26    14:22 成绩 正题 T1:NOI.AC−T1:NOI.AC-T1:NOI.AC− ...

  7. noi.ac 405 bzoj 4403 序列统计 题解

    博客观赏效果更佳 题意简述 noi.ac再次蒯题,实锤了- 请你求长度在 [ 1 , n ] [1,n] [1,n] 范围内,值域在 [ l , r ] [l,r] [l,r] 范围内的序列中,不下降 ...

  8. noi.ac 邀请赛1 By cellur925

    A. array 考场:上来就想暴力,首先第一个子任务肯定没问题,怎么搞都行.然后第二个子任务用个数组记下新修的值就行了.第三个子任务用一下等差数列求和公式帮助求解,每次都重新算(因为每次改变全部元素 ...

  9. noi.ac NOIP2018 全国热身赛 第四场 T1 tree

    [题解] 考虑从小到大枚举边权,按顺序加边. 当前树被分成了若干个联通块,若各个块内的点只能跟块外的点匹配,那么最终的min g(i,pi)一定大于等于当前枚举的边. 判断各个联通块内的点是否全部能跟 ...

最新文章

  1. Linux+mysql重置_linux环境mysql重置密码
  2. js原型和原型链_JS里的原型和原型链
  3. 计算机任务驱动法教学应用,任务驱动教学法在计算机教学中的应用
  4. leetcode746. 使用最小花费爬楼梯
  5. 如果您不将Docker用于数据科学项目,那么您将生活在1985年
  6. 安装翻译_百度翻译下载安装官方地址
  7. 交互系统的构建之(一)重写Makefile编译TLD系统
  8. 作为一个程序员必备的素质
  9. 模态框分页java代码_ajax分页效果(bootstrap模态框)
  10. 如何直接删除mysql中的重复数据_如何删除mysql数据库中重复的数据(部分重复)?...
  11. 《jQuery、jQuery UI及jQuery Mobile技巧与示例》——3.5 技巧:更改元素的HTML内容...
  12. 单片机数码管万年历c语言,基于51单片机和数码管的万年历程序
  13. SQL注入的常见方式
  14. 2009英国电子工程学专业排名
  15. [USACO19FEB]Mowing Mischief
  16. 【JAVA长虹键法】第 十二式 外观模式(23种设计模式)
  17. Lenet5实现及代码详解——以MINST数据集为例
  18. 跨部门的高效沟通与协作
  19. 【ELK】ELK菜鸟手记 (一) 环境配置+log4j日志记录——转自Master HaKu
  20. C语言中的void 和void 指针类型

热门文章

  1. redis深度历险 pdf_程序员面试必备精选文档:Redis+Ng+Tomcat+并发编程+Spring系列
  2. 工资10000元,应该交多少税?
  3. 冬天你的车热的正确吗?如何正确热车?
  4. 人不能轻易暴露自己的底牌,否则会陷入被动的局面
  5. 1000个网络摄像头如何组网?
  6. 模型训练:数据预处理和预载入
  7. Error: failed to unmarshal json. invalid character '\'' looking for beginning of value解决方案
  8. 如何配置 Linux ipv6 6RD隧道
  9. java ajax传递到action_ajax传值到action,后台取不到值。
  10. azure 使用_使用Azure Data Studio开始您的旅程