http://acm.hdu.edu.cn/showproblem.php?pid=2292

题意:1-n个节点,题目给出了完全二叉树的定义(这个定义似乎有歧义,此题以题目描述为准),且要保持最小堆性质(根节点小于左右子树内的任意元素),问有多少种不同组合

解法:dp,dp[n]表示n个元素的合法排列数量。一共n个节点,左子树有a个节点,则右子树有n-1-a个节点,dp[n]=C(n-1,a)*dp[a]*dp[n-1-a],其中a可以轻易算出。

公式解释:除去根节点,在剩下的n-1个元素中取a个,这a个元素的合法排列有dp[a]种,剩下n-1-a个节点的合法排列有dp[n-1-a]种。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;
typedef __int64 ll ;
ll c[][],n,m,dp[] ;
ll cal(int s)
{
ll temp=s- ;
ll cnt= ;
ll ans= ;
while(temp-cnt>)
{
ans+=cnt/ ;
temp-=cnt ;
cnt*= ;
}
if(temp>=cnt/)ans+=cnt/ ;
else ans+=temp ;
return ans ;
}
int main()
{
int t ;
scanf("%d",&t) ;
while(t--)
{
scanf("%I64d%I64d",&n,&m) ;
memset(c,,sizeof(c)) ;
for(int i= ;i< ;i++)
{
c[i][]=c[i][i]= ;
for(int j= ;j<i ;j++)
c[i][j]=(c[i-][j-]+c[i-][j])%m ;
}
memset(dp,,sizeof(dp)) ;
dp[]=dp[]= ;
for(int i= ;i<=n ;i++)
{
ll a=cal(i) ;
ll b=i--a ;
dp[i]=c[i-][a]*dp[a]%m*dp[b]%m ;
}
printf("%I64d\n",dp[n]%m) ;
}
return ;
}

最新文章

  1. DP4J -- mnist
  2. android:layout_weight的真实含义(转)
  3. shell 统计某个文件的行数命令
  4. 更改codeblocks的配色方案
  5. android应用锁之获取前台进程包名方法
  6. Thrift编译与验证 - python
  7. runv start container 流程分析
  8. oracle.jbo.JboException: JBO-29000: JBO-29000: Bad version number in .class file
  9. oracle-1
  10. mongodb查询文档
  11. WCF服务端行为的一些设置
  12. 通用sqlserver分页存储过程
  13. Ajax Array Json 示例
  14. RESTful API 设计最佳实践(转)
  15. gitlab一键安装
  16. 对consistencygroup的一些研究和实践
  17. Linux进程管理(-)
  18. 手把手使用Git?
  19. sortable.js 拖拽排序及配置项说明
  20. Lua中的协同程序

热门文章

  1. arthas使用介绍
  2. HDU1698:Just a Hook(线段树区域更新模板题)
  3. HDU5124:lines(线段树+离散化)或(离散化思想)
  4. 记录:EPALN Electric P8 2.4.4.8366 安装记录
  5. zw“小数据”理论也碰上了“黑天鹅”
  6. Python Missing parentheses in call to &#39;print&#39;
  7. Tomcat环境变量设置
  8. 面试官问:JS的this指向
  9. JAVA面试题整理(6)-JVM
  10. MFC读写EXIF信息,图片非占用