Description

题库链接

询问有多少个 \(1\sim N\) 的排列 \(P\) 满足“ \(\forall i\in[2,N], P_i>P_{\frac{i}{2}}\) ” 。对质数 \(P\) 取模。

\(1\leq N\leq 1000000,1\leq P\leq 10^9\)

Solution

容易发现满足题目需要的性质的序列就是满足堆性质的。那么可以在树(堆)上 \(DP\) 。

记 \(f_o\) 为在 \(o\) 节点及其子树中满足条件的编号方法数。

显然 \[f_o=f_{2o}f_{2o+1}C_{size_{2o}+size_{2o+1}}^{size_{2o}}\]

注意由于 \(p\) 不一定大于 \(n\) ,所以不能直接求逆。

Code

//It is made by Awson on 2018.3.22
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 1e6;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); } int n, p, a[N+5], b[N+5], f[N+5], size[N+5], num[N+5]; int C(int n, int m) {
if (num[n]-num[n-m]-num[m] == 0) return 1ll*a[n]*b[n-m]%p*b[m]%p;
return 0;
}
int dfs(int o) {
if (o*2 > n) {f[o] = 1; return size[o] = 1; }
if (o*2+1 > n) {size[o] = dfs(o*2)+1; f[o] = f[o*2]; return size[o]; }
size[o] = 1+dfs(o*2)+dfs(o*2+1);
f[o] = 1ll*f[o*2]*f[o*2+1]%p*C(size[o*2]+size[o*2+1], size[o*2+1])%p;
return size[o];
}
void work() {
read(n); read(p);
a[0] = b[0] = a[1] = b[1] = 1;
for (int i = 2; i <= n; i++) {
if (i%p) b[i] = -1ll*(p/i)*b[p%i]%p;
else b[i] = 1;
}
for (int i = 2; i <= n; i++) {
b[i] = 1ll*b[i]*b[i-1]%p;
if (i%p) a[i] = 1ll*a[i-1]*i%p;
else a[i] = a[i-1];
}
for (int i = 2; i <= n; i++) {
num[i] = num[i-1];
if (i%p == 0) {
int x = i;
while (x%p == 0) ++num[i], x /= p;
}
}
dfs(1); writeln((f[1]+p)%p);
}
int main() {work(); return 0; }

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

  1. 「ZJOI 2010」 排列计数

    题目链接 戳我 \(Solution\) 其实我们可以发现这题等价于让你求: 用\(1\)~\(n\)的数组成一个完全二叉树使之满足小根堆性质的方案数 于是我们可以考虑\(dp\) 假设我们现在在\( ...

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

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

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

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

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

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

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

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

  6. Perm排列计数(新博客试水,写的不好,各路大神见谅)

    B. Perm 排列计数 内存限制:512 MiB 时间限制:1000 ms 标准输入输出   题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i&l ...

  7. 【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas

    [题目]BZOJ 2111 [题意]求有多少1~n的排列,满足\(A_i>A_{\frac{i}{2}}\),输出对p取模的结果.\(n \leq 10^6,p \leq 10^9\),p是素数 ...

  8. BZOJ2111: [ZJOI2010]Perm 排列计数

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2111 题意:一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2< ...

  9. bzoj2111 Perm 排列计数

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

随机推荐

  1. 蓝桥杯java历年真题及答案整理1~20.md

    蓝桥杯java历年真题及答案整理(闭关一个月,呕心沥血整理出来的) 1 算法是这样的,如果给定N个不同字符,将这N个字符全排列,最终的结果将会是N!种.如:给定 A.B.C三个不同的字符,则结果为:A ...

  2. 2017级C语言教学总结

    一个学期下来,对于这门课教学还是感受挺多,多个教学平台辅助,确实和我前10年的教学方式区别很多,也辛苦很多. 一.课堂教学方面 1.课堂派预习作业 主要借助课堂派平台,每次课前发布预习作业.而预习作业 ...

  3. C语言第三周作业---单层循环

    一.PTA实验作业 题目1 1.实验代码 int N = 0,i; char sex; float a[9], height; scanf("%d\n", &N); for ...

  4. Alpha冲刺No.1

    冲刺Day1 一.站立式会议计划 全体成员先安装好Android Studio,mysql,以及navicat for MySQL 将上述软件调试至可运行状态 自主把玩安卓虚拟机,mysql 通过一些 ...

  5. Python 实现队列

    操作 Queue() 创建一个空的队列 enqueue(item) 往队列中添加一个item元素 dequeue() 从队列头部删除一个元素 is_empty() 判断一个队列是否为空 size() ...

  6. 2017-2018-1 我爱学Java 第八周 作业

    团队六七周作业 团队分工 UML图 工具选择 小编(金立清)有话说 参考资料 团队分工 返回目录 UML图 用例图 类图 活动图 状态图 返回目录 工具选择 ProcessOn - 免费在线作图,实时 ...

  7. 20145237 实验五《Java网络编程》

    20145237 实验五<Java网络编程> 一.实验内容 •1.运行下载的TCP代码,结对进行,一人服务器,一人客户端: •2.利用加解密代码包,编译运行代码,一人加密,一人解密: •3 ...

  8. android使用sharesdk的小感

    1.sharesdk快捷方式,快捷方式集成了所有需要分享到的手机app,但是具有缺陷,举个例子(想要微信分享图片url,但是短信并不想带有图片,否则短信成彩信,这里集成的就有麻烦了,为了解决这种问题, ...

  9. python的dir、help、str用法

    当你给dir()提供一个模块名字时,它返回在那个模块中定义的名字的列表.当没有为其提供参数时, 它返回当前模块中定义的名字的列表.dir() 函数使用举例: 1 2 3 4 5 6 >>& ...

  10. python 关键字的操作

    声明:本文章默认使用的是python 3.6.1 1.要想当个牛逼的程序员,就要精通各种hello world的写法,当然,我不牛逼,只能用python去写^..^! print("Hell ...