数据范围:$1 \leq N \leq 10^6, P \leq 10^9 $
这个题……
以为是排列,其实是组合
题目中说是从所有排列中找到Magic的,就是
$p_{i/2} \leq p_i$ 满足的情况
我拿着排列想了半天,发现
这个题和排列一点关系也没有
而且我打了几个表,看了下可行结果,也不能逆向求
后来是一个提示:用堆,dp
堆啊……
我扯了一会大根堆,发现堆的形态有不确定性,dp起来费力耗时

所以就是小根堆了:小根堆的形态不变,只要找填数的方案,

那么这里如何做呢?

对于每一个叶子节点和唯一值,只有一种方案

然后对于根节点,比根大的数作为叶节点,只要分成两部分就可以

但是如何分也不必要记录,只要记录方案数

由于是分步求解,

所以要把每个子树上的方法与本次分的方法相乘。

式子:$dp[i]=C_{siz[i]-1}^{siz[2*i]}*dp[i*2]*dp[i*2+1]$其中$siz[i]$是以$i$为根的树节点数

于是就可以得到结果$dp[1]$

当然要从$n$跑到$1$了

下面是另一部分

$C_n^m\%p$怎么求?

卢卡斯定理,p一定要是素数。

具体证明和代码见这里

蒟蒻不会了~~

然后里面的细节就是,求阶乘及其逆元,可以打表,现求逆元也可以。

用 $a^{p-2}$ 的快速幂求逆元

 #include <iostream>
#include <cstdio>
#include <algorithm>
#define N 2000100
#define LL long long
using namespace std;
LL p,n;
int siz[N];
LL fac[N],inv[N],dp[N];
LL ppow(LL a,LL b){
LL k=;
while(b){
if(b&)k=k*a%p;
a=a*a%p;
b>>=;
}
return k;
}
void prerun(){
for (int i=n;i>=;i--){
siz[i]=siz[i*]+siz[i*+]+;
}
fac[]=;
for (int i=;i<=n;i++){
fac[i]=fac[i-]*i%p;
}
}
LL C(LL m,LL n){
if(n<m)return ;
return fac[n]*ppow(fac[m],p-)%p*ppow(fac[n-m],p-)%p;
}
LL lucas(LL m,LL n){
if(m==)return ;
return lucas(m/p,n/p)*C(m%p,n%p)%p;
}
int main (){
scanf("%lld%lld",&n,&p);
prerun();
for (int i=n;i>=;i--){
dp[i]=lucas(siz[i*],siz[i]-);
if(i*<=n)dp[i]=dp[i]*dp[i*]%p;
if(i*+<=n)dp[i]=dp[i]*dp[i*+]%p;
}
printf("%lld\n",dp[]);
return ;
}

真不知道没有题解怎么活~~

主要参考:Rorschach_XR的[ZJOI2010]排列计数 题解

组合数学起步-排列计数[ZJOI2010][BZOJ2111]的更多相关文章

  1. 【BZOJ2111】[ZJOI2010]排列计数(组合数学)

    [BZOJ2111][ZJOI2010]排列计数(组合数学) 题面 BZOJ 洛谷 题解 就是今年九省联考\(D1T2\)的弱化版? 直接递归组合数算就好了. 注意一下模数可以小于\(n\),所以要存 ...

  2. 【BZOJ2111】[ZJOI2010]Perm 排列计数 组合数

    [BZOJ2111][ZJOI2010]Perm 排列计数 Description 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi> ...

  3. BZOJ 2111: [ZJOI2010]Perm 排列计数 [Lucas定理]

    2111: [ZJOI2010]Perm 排列计数 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1936  Solved: 477[Submit][ ...

  4. BZOJ_4517_[Sdoi2016]排列计数_组合数学

    BZOJ_4517_[Sdoi2016]排列计数_组合数学 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[ ...

  5. 2111: [ZJOI2010]Perm 排列计数

    2111: [ZJOI2010]Perm 排列计数 链接 题意: 称一个1,2,...,N的排列$P_1,P_2...,P_n$是Magic的,当且仅当$2<=i<=N$时,$P_i> ...

  6. bzoj 2111: [ZJOI2010]Perm 排列计数 (dp+卢卡斯定理)

    bzoj 2111: [ZJOI2010]Perm 排列计数 1 ≤ N ≤ 10^6, P≤ 10^9 题意:求1~N的排列有多少种小根堆 1: #include<cstdio> 2: ...

  7. [ZJOI2010]排列计数 (组合计数/dp)

    [ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有 ...

  8. 洛谷 P2606 [ZJOI2010]排列计数 解题报告

    P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...

  9. P2606 [ZJOI2010]排列计数

    P2606 [ZJOI2010]排列计数 因为每个结点至多有一个前驱,所以我们可以发现这是一个二叉树.现在我们要求的就是以1为根的二叉树中,有多少种情况,满足小根堆的性质. 设\(f(i)\)表示以\ ...

随机推荐

  1. 乌云精华漏洞整合(epub)

    还是7月份的 链接: http://pan.baidu.com/s/1kUGIOez 密码: gfqp

  2. 初探Remax微信小程序

    1.创建项目 npx degit remaxjs/template-wechat my-app cd my-app && npm install 2.运行项目 npm run dev ...

  3. nodejs实现读取文件

    今天后端同事下班,想让我读取一个文件的内容.我想这个是小忙啊,就立马答应了. 我知道这个是nodejs读取,可是我又想,平时我们都要起一个服务才能够运行node服务器, 比如如下代码 var http ...

  4. c++ static关键字的作用

    1.被申明的函数或值无法被其他源文件使用 2.static的第二个作用是保持变量内容的持久.(static变量中的记忆功能和全局生存期) 存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯 ...

  5. Zuul上传文件

    对于1M以内的文件上传,无需任何处理,大文件10M以上需要为上传路径添加/zuul前缀,也可使用zuul.servlet-path自定义前缀 如果Zuul使用了Ribbon做负载均衡,那么对于超大的文 ...

  6. Vue.js项目部署到服务器

    1.申请服务器 2.配置Xshell 3.在服务器手动建自己的根目录,把根目录的文件名复制给项目里面config下面的index.js 4.项目开始打包 npm run build 5.打包完成之后把 ...

  7. iOS之CATiledLayer的属性简介和使用

    1.CATiledLayer简介 CATiledLayer用于大型图片进行分割显示,需要显示的图片才会加载,直接上代码: - (void)viewDidLoad { [super viewDidLoa ...

  8. 转:Wireshark基本介绍和学习TCP三次握手

    源地址:http://www.cnblogs.com/TankXiao/archive/2012/10/10/2711777.html 之前写过一篇博客:用 Fiddler 来调试HTTP,HTTPS ...

  9. hibernate查询timestamp条件

    参考https://blog.csdn.net/zuozuoshenghen/article/details/50540661 Mysql中Timestamp字段的格式为yyyy-MM-dd HH-m ...

  10. <每日一题>题目23:桶排序

    ''' 桶排序:最快最简单的排序 缺点:最占内存 类型:分布式排序 ''' import cProfile import random def bucketSort(nums): #选出最大的数 ma ...