当前位置: 首页 > news >正文

P2606 [ZJOI2010] 排列计数 分析

题目概述

题目链接:https://www.luogu.com.cn/problem/P2606。

称一个 \(1 \sim n\) 的排列 \(p_1,p_2, \dots ,p_n\) 是 Magic 的,当且仅当

\[\forall i \in [2,n],p_i > p_{\lfloor i/2 \rfloor} \]

计算 \(1 \sim n\) 的排列中有多少是 Magic 的,答案可能很大,只能输出模 \(m\) 以后的值。

对于 \(100\%\) 的数据,\(1\le n \le 10^6\), \(1\le m \le 10^9\)\(m\) 是一个质数。

分析1

这显然是一个小根堆,那么直接设 \(f_i\) 表示大小为 \(i\) 的排列(经典)满足小根堆性质的方案。

显然钦定第一个节点为 \(1\),然后就有:

\[f_{i}=\binom{i-1}{l}f_l\times f_r \]

其中 \(l\) 是这个完全二叉树左子树的大小。

分析2

巧法:考虑将计数问题转化为概率问题

我们可以求出满足这个条件的概率,最后在乘上总方案就行了,有时候概率题也可以用计数题的方法。

我们考虑一个大小为 \(k\) 的子树,那么显然我当前这个点满足小根堆的性质当且仅当为这里面的最小值,所以概率是 \(\frac{1}{k}\)

所以 \(n\) 个点满足的概率为 \(\frac{1}{\prod_i sz_i}\),那么所有的答案为 \(\frac{n!}{\prod_i sz_i}\)

代码

只有分析二的代码,分析一的我没有打(因为感觉分析二的方法更通用一点)。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define int long long
#define N 2000006
using namespace std;
int n,mod;
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
int sz[N],inv[N],jc[N];
int ans = 1,fz,fm;
int qpow(int a,int b) {int res = 1;while(b) {if (b & 1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}
void dfs(int cur) {sz[cur] = 1;if (ls(cur) <= n) dfs(ls(cur));if (rs(cur) <= n) dfs(rs(cur));sz[cur] += sz[ls(cur)] + sz[rs(cur)];int t = sz[cur];while(t % mod == 0) fm ++,t /= mod;ans = ans * inv[t % mod] % mod;
}
int f(int n,int m) {if (n / m <= 0) return 0;return n / m + f(n / m,m);
}
signed main(){cin >> n >> mod;jc[0] = jc[1] = inv[0] = inv[1] = 1;for (int i = 2;i <= n;i ++) jc[i] = jc[i - 1] * i % mod;for (int i = 2;i <= min(n,mod - 1);i ++) inv[i] = (mod - mod / i) * inv[mod % i] % mod;dfs(1);fz = f(n,mod);if (fz > fm) return cout << 0,0;else {for (int i = 1;i <= n;i ++) {int t = i;while (t % mod == 0) t /= mod;ans = ans * t % mod;}cout << ans;}return 0;
}
//7 3
http://www.hskmm.com/?act=detail&tid=38349

相关文章:

  • 分治算法乱讲
  • 电动三轮车后桥改造添加动能回收实现无限续航的可能。
  • Claude Code配置记录
  • 视频融合平台EasyCVR在智慧工地中的应用:构建安全、智能、高效的“云上工地” - 实践
  • 股票操作统计分析报告 - 2025年10月24日
  • [HZOI] CSP-S模拟37 赛后总结
  • 24
  • 数字人:数字人公司排行榜及技术深度剖析
  • 【同余最短路】学习笔记
  • 数字人:数字人公司深度解析与未来展望
  • CSP/NOIP 复习:单调栈
  • 算法分析--生成排列
  • 三大安全认证授权协议深度对比:OAuth、OpenID Connect与SAML
  • 数字人公司:数字人新趋势技术驱动与市场前景解析
  • AI股票预测分析报告 - 2025年10月24日
  • 数据绑定相关概念理解
  • 数字人企业:数字人公司排行榜Top 3解析
  • (简记)(自用)线段树区间拆分时间复杂度证明
  • 数字人企业:数字人公司排行榜深度解析
  • 数字人:怎么选择数字人实力公司
  • 拉格朗日插值优化DP
  • 冬日绘板 2026 珂朵莉计划 如何获取 Token
  • 数字人企业:数字人公司技术驱动的三大标杆
  • Linux下的拼音输入法 (2)
  • 数字人平台:重点推荐优质数字人公司
  • SpringBoot整合缓存2-Redis
  • 数字人企业:推荐数字人TOP3公司
  • NOI25D2T2
  • 时钟同步
  • 深入解析:【Java系列课程Java学前须知】第3课 JDK,JVM,JRE的区别和优缺