[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=2111

[算法]

一种比较好的理解方式是将该序列看成是一棵堆式存储的二叉树

那么问题转化为求有多少个堆

考虑dp , 用fi表示以i为根的子树能构成多少个堆

根结点显然是最小的数 , 我们要在剩余的(sizei - 1)个数中选出size(2i)个数 , 然后分配至左右子树中

显然 , fi = C(sizei - 1 , size(2i)) * f(2i) * f(2i + 1)

预处理阶乘和逆元 , 用lucas定理求组合数即可

时间复杂度 : O(N)

[代码]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 2e6 + ; int n , P;
int fac[N] , inv[N] , size[N]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline int exp_mod(int a , int n)
{
int res = , b = a;
while (n > )
{
if (n & ) res = 1ll * res * b % P;
b = 1ll * b * b % P;
n >>= ;
}
return res;
}
inline void init()
{
fac[] = ;
for (int i = ; i <= min(n , P - ); i++) fac[i] = 1ll * fac[i - ] * i % P;
inv[min(n , P - )] = exp_mod(fac[min(n , P - )] , P - );
for (int i = min(n , P - ) - ; i >= ; i--) inv[i] = 1ll * inv[i + ] * (i + ) % P;
}
inline int C(int x , int y)
{
if (!y) return ;
if (x == y) return ;
if (x < y) return ;
return 1ll * fac[x] * inv[y] % P * inv[x - y] % P;
}
inline int lucas(int x , int y)
{
if (!y) return ;
if (x < P && y < P) return C(x , y);
return 1ll * lucas(x / P , y / P) * C(x % P , y % P) % P;
}
inline int dp(int u)
{
if (u > n) return ;
return 1ll * lucas(size[u] - , size[u << ]) * dp(u << ) % P * dp(u << | ) % P;
} int main()
{ read(n); read(P);
init();
for (int i = ; i <= n; i++) size[i] = ;
for (int i = n; i >= ; i--) size[i >> ] += size[i];
printf("%d\n" , dp()); return ; }

[ZJOI 2010] 排列计数的更多相关文章

  1. [ZJOI 2010] 数字计数

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1833 [算法] 数位DP [代码] #include <algorithm&g ...

  2. BZOJ 4517: [Sdoi2016]排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 911  Solved: 566[Submit][Status ...

  3. bzoj-4517 4517: [Sdoi2016]排列计数(组合数学)

    题目链接: 4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 846  Solved: 530[Submit][ ...

  4. ACM/ICPC 之 DP-浅谈“排列计数” (POJ1037)

    这一题是最近在看Coursera的<算法与设计>的公开课时看到的一道较难的DP例题,之所以写下来,一方面是因为DP的状态我想了很久才想明白,所以借此记录,另一方面是看到这一题有运用到 排列 ...

  5. 数学(错排):BZOJ 4517: [Sdoi2016]排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 693  Solved: 434[Submit][Status ...

  6. 【数论·错位排列】bzoj4517 排列计数

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1428  Solved: 872[Submit][Statu ...

  7. BZOJ 4517: [Sdoi2016]排列计数 [容斥原理]

    4517: [Sdoi2016]排列计数 题意:多组询问,n的全排列中恰好m个不是错排的有多少个 容斥原理强行推♂倒她 $恰好m个不是错排 $ \[ =\ \ge m个不是错排 - \ge m+1个不 ...

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

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

  9. bzoj4517排列计数 错排+组合

    4517: [Sdoi2016]排列计数 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 1491  Solved: 903[Submit][Statu ...

随机推荐

  1. Android开源工具项目集合

    最近因为要去外派了,工欲善其事,必先利其器!所以又回顾了一下自己github上所收藏的项目,也算是温故而知新吧. 最流行的Android组件大全 http://www.open-open.com/li ...

  2. C - The C Answer (2nd Edition) - Exercise 1-16

    /* Revise the main routine of the longest-line program so it will correctly print the length of arbi ...

  3. 编写自己的UDTF

    1. UDTF介绍 UDTF(User-Defined Table-Generating Functions) 用来解决 输入一行输出多行(On-to-many maping) 的需求. 2. 编写自 ...

  4. 小白学phoneGap《构建跨平台APP:phoneGap移动应用实战》连载一(PhoneGap中的API)

    之前本博连载过<构建跨平台APP:jQuery Mobile移动应用实战>一书.深受移动开发入门人员的喜爱. 从如今開始,连载它的孪生姐妹书phoneGap移动应用实战一书,希望以前是小白 ...

  5. java内存模型(Java Memory Model)

    内容导航: Java内存模型 硬件存储体系结构 Java内存模型和硬件存储体系之间的桥梁: 共享对象的可见性 竞争条件 Java内存模型规定了JVM怎样与计算机存储系统(RAM)协调工作.JVM是一个 ...

  6. js 字符串常用方法

    数组方面 1.push:向数组尾部增加内容,返回的是新数组的长度. var arr = [1,2,3]; console.log(arr); var b = arr.push(4); console. ...

  7. c语言-递推算法1

    递推算法之一:倒推法 1.一般分析思路: if 求解初始条件F1 then begin { 倒推 } 由题意(或递推关系)确定最终结果Fn; 求出倒推关系式Fi-1 =G(Fi ); i=n; { 从 ...

  8. hdu5296(2015多校1)--Annoying problem(lca+一个公式)

    Annoying problem Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  9. java 堆和栈一般理解

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同.Java自己主动管理栈和堆.程序猿不能直接地设置栈或堆.  Java的堆是一个执行时数据区,类的(对象从中分配空间.这些对象通过new.n ...

  10. JavaScript2种构造函数创建对象的模式以及继承的实现

    第一种模式: function Person(){ } Person.prototype.say=function(){ alert('hello'); } var person=new Person ...