题目描述

称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大,只能输出模P以后的值

输入输出格式

输入格式:

输入文件的第一行包含两个整数 n和p,含义如上所述。

输出格式:

输出文件中仅包含一个整数,表示计算1,2,⋯, ���的排列中, Magic排列的个数模 p的值。

输入输出样例

输入样例#1: 复制

20 23 
输出样例#1: 复制

16

说明

100%的数据中,1 ≤N ≤ 10^6, P≤ 10^9,p是一个质数。

题解

 数位dp?这怕不是个树位dp……

  我们把原序列看成一棵二叉树

  那么就是要我们求大小为$n$的小根堆有多少个(就是父节点比左右儿子都小)

  那么考虑dp,设$dp[i]$表示有多少个大小为$i$的小根堆,$val[i]$表示$i$的子树的大小

  因为父亲必须小于儿子,所以根节点只能是最小的点,那么剩下的$i-1$个点里有$val[l]$个可以放在左子树,剩下的都可以放在右子树,方案数为$C_{i-1}^{val[l]}$

  然后因为选不同的点之后还能有不同的方案,所以还要乘上方案数

  所以最后的状态转移方程是这样的$dp[i]=C_{i-1}^{val[l]}*dp[val[l]]*dp[val[r]]$

  然后因为要组合数取模,得用上Lucas定理

 //minamoto
#include<cstdio>
#define ll long long
const int N=1e6+;
ll inv[N],fac[N],val[N],dp[N],n,mod;
#define min(a,b) ((a)<(b)?(a):(b))
ll qpow(ll x,ll y){
ll res=;
while(y){
if(y&) res=res*x%mod;
y>>=,x=x*x%mod;
}
return res;
}
void init(){
int k=min(n,mod-);
fac[]=fac[]=;
for(int i=;i<=k;++i) fac[i]=fac[i-]*i%mod; inv[k]=qpow(fac[k],mod-);
for(int i=k-;i;--i) inv[i]=(i+)*inv[i+]%mod;
}
ll C(ll n,ll m){
if(m>n) return ;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
ll Lucas(ll n,ll m){
if(m==||m==n) return ;
return Lucas(n/mod,m/mod)*C(n%mod,m%mod)%mod;
}
int main(){
//freopen("testdata.in","r",stdin);
scanf("%lld%lld",&n,&mod);init();
for(int i=n;i;--i){
val[i]=;if((i<<)<=n) val[i]+=val[i<<];if((i<<|)<=n) val[i]+=val[i<<|];
if((i<<|)<=n) dp[i]=Lucas(val[i]-,val[i<<])*dp[i<<]%mod*dp[i<<|]%mod;
else if((i<<)<=n) dp[i]=dp[i<<];
else dp[i]=;
}
printf("%lld\n",dp[]);
return ;
}

洛谷P2606 [ZJOI2010]排列计数(数位dp)的更多相关文章

  1. 洛谷P2606 [ZJOI2010]排列计数(组合数 dp)

    题意 题目链接 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案 ...

  2. 洛谷P2606 [ZJOI2010]排列计数 组合数学+DP

    题意:称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大, ...

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

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

  4. ●洛谷P2606 [ZJOI2010]排列计数

    题链: https://www.luogu.org/problemnew/show/P2606题解: 组合数(DP),Lucas定理 首先应该容易看出,这个排列其实是一个小顶堆. 然后我们可以考虑dp ...

  5. 洛谷P2606 [ZJOI2010]排列计数

    题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很 ...

  6. 洛谷P2602 [ZJOI2010]数字计数(数位dp)

    数字计数 题目传送门 解题思路 用\(dp[i][j][k]\)来表示长度为\(i\)且以\(j\)为开头的数里\(k\)出现的次数. 则转移方程式为:\(dp[i][j][k] += \sum_{t ...

  7. P2606 [ZJOI2010]排列计数

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

  8. 洛谷P2602 [ZJOI2010]数字计数 题解 数位DP

    题目链接:https://www.luogu.com.cn/problem/P2602 题目大意: 计算区间 \([L,R]\) 范围内 \(0 \sim 9\) 各出现了多少次? 解题思路: 使用 ...

  9. 洛谷 P2602 [ZJOI2010]数字计数

    洛谷 第一次找规律A了一道紫题,写篇博客纪念一下. 这题很明显是数位dp,但是身为蒟蒻我不会呀,于是就像分块打表水过去. 数据范围是\(10^{12}\),我就\(10^6\)一百万一百万的打表. 于 ...

随机推荐

  1. Day2-Python基础2---集合和文件操作

    一.集合操作 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 s = set([1,4,5,7,3, ...

  2. Dataguard ORA-19909 ORA-01110

    在创建ORACLE 10G Dataguard时,报错: Datafile 1 (ckpscn 24967685451) is orphaned on incarnation#=6 MRP0: Bac ...

  3. Spring装配各种类型bean

    一.单属性值的装配 //setter注入,提供无参构造器,提供setXX方法 <property name="" value=""></pro ...

  4. python之简单的函数介绍(http://docs.python.org/3/library)

    Python不但能非常灵活地定义函数,而且本身内置了很多有用的函数,可以直接调用. 在上面的网站上我们可以进行查询,Python具体都有哪些函数. 我们也可以再交互命令行中来查找函数: >> ...

  5. sqlplus--spool基础运用

    set heading offset feedback offset echo offset newp noneset termout offspool /home/orarun/scripts/da ...

  6. SQL基础E-R图基础

    ER图分为实体.属性.关系三个核心部分.实体是长方形体现,而属性则是椭圆形,关系为菱形. ER图的实体(entity)即数据模型中的数据对象,例如人.学生.音乐都可以作为一个数据对象,用长方体来表示, ...

  7. oracle 常用set命令

    SQL> set timing on;           //设置显示“已用时间:XXXX”SQL> set autotrace on;        //设置允许对执行的sql进行分析 ...

  8. PHP处理密码的几种方式

    在 PHP中,经常会对用户身份进行认证.本文意在讨论对密码的处理,也就是对密码的加密处理. 1.MD5 相信很多PHP开发者在最先接触PHP的时候,处理密码的首选加密函数可能就是MD5了,我当时就是这 ...

  9. Codeforces 57C (1-n递增方案数,组合数取模,lucas)

    这个题相当于求从1-n的递增方案数,为C(2*n-1,n); 取模要用lucas定理,附上代码: #include<bits/stdc++.h> using namespace std; ...

  10. Ros学习——C++发布器publisher和订阅器subscriber

    1.编写发布器 初始化 ROS 系统 在 ROS 网络内广播我们将要在 chatter 话题上发布 std_msgs/String 类型的消息 以每秒 10 次的频率在 chatter 上发布消息 在 ...