NOI.AC #31. MST
好像又是神仙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相关推荐
- NOI.AC NOIP模拟赛 第六场 游记
NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...
- NOI.AC#2007-light【根号分治】
正题 题目链接:http://noi.ac/problem/2007 题目大意 nnn个格子排成一排,每个格子有一个0/10/10/1和一个颜色.开始每个格子都是000,qqq次操作取反一个颜色的所有 ...
- NOI.AC#2139-选择【斜率优化dp,树状数组】
正题 题目链接:http://noi.ac/problem/2139 题目大意 给出nnn个数字的序列aia_iai.然后选出一个不降子序列最大化子序列的aia_iai和减去没有任何一个数被选中的 ...
- NOI.AC#2144-子串【SAM,倍增】
正题 题目链接:http://noi.ac/problem/2144 题目大意 给出一个字符串sss和一个序列aaa.将字符串sss的所有本质不同子串降序排序后,求有多少个区间[l,r][l,r][l ...
- NOI.AC#2266-Bacteria【根号分治,倍增】
正题 题目链接:http://noi.ac/problem/2266 题目大意 给出nnn个点的一棵树,有一些边上有中转站(边长度为222,中间有一个中转站),否则就是边长为111. mmm次询问一个 ...
- 野鸡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− ...
- noi.ac 405 bzoj 4403 序列统计 题解
博客观赏效果更佳 题意简述 noi.ac再次蒯题,实锤了- 请你求长度在 [ 1 , n ] [1,n] [1,n] 范围内,值域在 [ l , r ] [l,r] [l,r] 范围内的序列中,不下降 ...
- noi.ac 邀请赛1 By cellur925
A. array 考场:上来就想暴力,首先第一个子任务肯定没问题,怎么搞都行.然后第二个子任务用个数组记下新修的值就行了.第三个子任务用一下等差数列求和公式帮助求解,每次都重新算(因为每次改变全部元素 ...
- noi.ac NOIP2018 全国热身赛 第四场 T1 tree
[题解] 考虑从小到大枚举边权,按顺序加边. 当前树被分成了若干个联通块,若各个块内的点只能跟块外的点匹配,那么最终的min g(i,pi)一定大于等于当前枚举的边. 判断各个联通块内的点是否全部能跟 ...
最新文章
- Linux+mysql重置_linux环境mysql重置密码
- js原型和原型链_JS里的原型和原型链
- 计算机任务驱动法教学应用,任务驱动教学法在计算机教学中的应用
- leetcode746. 使用最小花费爬楼梯
- 如果您不将Docker用于数据科学项目,那么您将生活在1985年
- 安装翻译_百度翻译下载安装官方地址
- 交互系统的构建之(一)重写Makefile编译TLD系统
- 作为一个程序员必备的素质
- 模态框分页java代码_ajax分页效果(bootstrap模态框)
- 如何直接删除mysql中的重复数据_如何删除mysql数据库中重复的数据(部分重复)?...
- 《jQuery、jQuery UI及jQuery Mobile技巧与示例》——3.5 技巧:更改元素的HTML内容...
- 单片机数码管万年历c语言,基于51单片机和数码管的万年历程序
- SQL注入的常见方式
- 2009英国电子工程学专业排名
- [USACO19FEB]Mowing Mischief
- 【JAVA长虹键法】第 十二式 外观模式(23种设计模式)
- Lenet5实现及代码详解——以MINST数据集为例
- 跨部门的高效沟通与协作
- 【ELK】ELK菜鸟手记 (一) 环境配置+log4j日志记录——转自Master HaKu
- C语言中的void 和void 指针类型
热门文章
- redis深度历险 pdf_程序员面试必备精选文档:Redis+Ng+Tomcat+并发编程+Spring系列
- 工资10000元,应该交多少税?
- 冬天你的车热的正确吗?如何正确热车?
- 人不能轻易暴露自己的底牌,否则会陷入被动的局面
- 1000个网络摄像头如何组网?
- 模型训练:数据预处理和预载入
- Error: failed to unmarshal json. invalid character '\'' looking for beginning of value解决方案
- 如何配置 Linux ipv6 6RD隧道
- java ajax传递到action_ajax传值到action,后台取不到值。
- azure 使用_使用Azure Data Studio开始您的旅程