数据范围:$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. JavaScript数组的2种定义方式

    JavaScript中没有数组类型,JavaScript中数组是以内置对象的形式存在的. 数组是存储多个值的集合(仓库). JS中定义数组的2种方式: 1.使用new Array()构造函数定义数组 ...

  2. python3 使用aria2下载的一个脚本

    import requests import time ariaurl="http://localhost:6800/jsonrpc" dlurl="http://xxx ...

  3. 第二章计算机网络ios 模型

    机构: ISO国际标准化组织: ITU国际电信联盟: ANSI 美国国家标准委员会: ECMA欧洲计算机制作商协会 ITEF因特网特别任务组. 协议:为计算机网路中进行数据交换而建立的规则,标准或约定 ...

  4. MVVM test

    示例代码 public class RegisterUserViewModel { public UserInfo userInfo { get; set; } public ICommand Cli ...

  5. [JZOJ4913] 【GDOI2017模拟12.3】告别

    题目 描述 题目大意 给你两个排列AAA和BBB,每次随即选三个数进行轮换操作,问mmm次操作内使AAA变成BBB的概率. 思考历程 首先随便搞一下,就变成了AAA中每个数回归自己原位. 一眼望去,感 ...

  6. CLOSE_WAIT问题讨论

    1.https://cloud.tencent.com/developer/article/1347610 2.https://blog.huoding.com/2016/01/19/488 3.ht ...

  7. System.Web.Mvc.HttpUnauthorizedResult.cs

    ylbtech-System.Web.Mvc.HttpUnauthorizedResult.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neut ...

  8. python用reduce和map把字符串转为数字的方法

    python用reduce和map把字符串转为数字的方法 最近在复习高阶函数的时候,有一道题想了半天解不出来.于是上午搜索资料,看了下别人的解法,发现学习编程,思维真的很重要.下面这篇文章就来给大家介 ...

  9. hdu 1754 I Hate It (线段树)

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 线段树的模板题,详细的都写在代码里了 //不知道为什么定义单个字符,用%c输入会超时,换成字符数 ...

  10. Django自带的认证系统

    Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Djang ...