首页 > 其他分享 >题解 [ZJOI2010]排列计数

题解 [ZJOI2010]排列计数

时间:2022-08-16 13:48:51浏览次数:56  
标签:return bas ZJOI2010 int 题解 计数 res fac Mod

好题。

% 你赛考到了不会摆烂,后来发现原来有向下取整,题面没有。。。(

就算有我也做不出来啦 qAq

首先我们会发现这个长得就是小根堆,答案就变成了小根堆的计数。

首先最小的数字肯定放在根的位置。我们令 \(f_i\) 为有 \(i\) 个数字组成的小根堆形态数量。显然小根堆左儿子和右儿子的数量是固定的,令左儿子 \(l\) 个右儿子 \(r\) 个,则显然有 \(f_i = C_{i - 1}^l\times f_l \times f_r\)。

组合数用 Lucas 求。

#include <iostream>
#define MAXN 1000000
using namespace std;
int n, m, Mod;
int qpow(int n, int m) {
	int res = 1, bas = n;
	while(m) {
		if(m & 1) res = res * bas % Mod;
		bas = bas * bas % Mod;
		m >>= 1;
	}
	return res;
} 
int fac[MAXN + 10];
void pre() {
	fac[0] = 1, fac[1] = 1;
	for(int p = 2; p <= MAXN; p++) fac[p] = fac[p - 1] * p % Mod;
}
int inv(int x) {
	return qpow(x, Mod - 2); 
}
int C(int n, int m) {//C_n^m
	if(m > n) return 0; 
	return fac[n] * inv(fac[m]) % Mod * inv(fac[n - m]) % Mod;
}
int Lucas(int n, int m) {//C_n^m
	if(!m) return 1;
	else return Lucas(n / Mod, m / Mod) * C(n % Mod, m % Mod) % Mod;
}
int f[MAXN + 10];
int main() {
	cin >> n >> Mod;
	pre();
	f[1] = 1, f[2] = 1, f[3] = 2;
	int l = 1, r = 1, lim = 3;
	for(int p = 4; p <= n; p++) {
		if(l < lim) l++;
		else r++;
		if(l == r) lim = (lim + 1) * 2 - 1;
		f[p] = Lucas(p - 1, l) * f[l] % Mod * f[r] % Mod;
	}
	cout << f[n] << endl; 
}

标签:return,bas,ZJOI2010,int,题解,计数,res,fac,Mod
From: https://www.cnblogs.com/thirty-two/p/16591251.html

相关文章

  • ubuntu16.04中文乱码问题解决
    1、先输入locale-a,查看一下现在已安装的语言2、若不存在如zh_CN之类的语言包,进行中文语言包装:apt-getinstalllanguage-pack-zh-hans3、安装好后我们可以进行临时修......
  • LeetCode 反转链表算法题解 All In One
    LeetCode反转链表算法题解AllInOnejs/ts实现反转链表反转链表原理图解双指针,swap交换//反转双指针//swap:a=b;c=a;b=c;letprev:List......
  • 洛谷P1714切蛋糕题解
    P1714切蛋糕题目描述今天是小Z的生日,同学们为他带来了一块蛋糕。这块蛋糕是一个长方体,被用不同色彩分成了\(n\)个相同的小块,每小块都有对应的幸运值。小Z作......
  • 【题解】【Shopping】【树上依赖型背包】
    很厉害的题。在任务计划里躺了一年。。。题目传送门思考之路题目要让我们在付出不超过m的代价在树上找到一个权值最大的连通块。容易想到树形dp,设\(f_{i,j}\)表示选的......
  • "蔚来杯"2022牛客暑期多校训练营7 题解
    C.ConstructiveProblemsNeverDie对于出现次数大于1的数字,用出现次数为0的数字填充。剩下的数字一定两两互不相同,对这些数循环移位,最后进行判断即可。#include<bits/......
  • CF1712B Woeful Permutation 题解
    题目传送门题目简介给定一个正整数\(n\),构造一个数列\(p\),使\(1\)到\(n\)中每一个数都出现且只出现\(1\)次。求最大的\(\sum\limits_{i=1}^n\operatorname......
  • Codeforces Round #813 (Div. 2) 题解A~E2
    https://codeforces.com/contest/1712估计也就我赛中才D都写不出来了A题题意:给你一个数组和一个正整数\(k\),每次可以选择数组的任意两个数交换,问你最少交换多少次能使......
  • CF1714C 题解
    题目大意找到最小的数字,使该数字每一位上的数字的和等于给定的数字\(s\),且其中的所有数字都不同,即所有数字都是唯一的。解法这题的数据很水,暴力就能过,从小到大枚举每......
  • ubuntu dpkg问题解决
    问题今天玩ubuntu发现以下报错:dpkgwasinterrupted,youmustmanuallyrunsudodpkg–configure-atocorrecttheproblem 解决sudorm/var/lib/apt/lists/l......
  • LGP8474题解
    很萌萌的数数题。考虑设\(dp[n]\)表示\(n\)的答案。考虑对于一个长度为\(n\)的排列,令排列的所有元素\(+1\),然后塞一个\(1\)进去。容易发现,逆序对增加的数量和......