题解:P10380 「ALFR Round 1」D 小山的元力

思路分析

考虑先求出 \(b_i\),枚举每个 \(i\)\(a_i\) 来求出 \(b_i\)。发现当前的 \(b_i\) 会对答案造成多次贡献,考虑求出造成多少贡献,原本的 \(n\) 个元素分为 \(m\) 组被转化为 \(n-a_i\) 个元素被分为 \(m-1\) 组有多少方案,可以为空。则答案就是 \(\binom{n-a_i+m-2}{m-2}\),详见插板法

进一步考虑,发现对于第 \(j\) 堆元素,其答案为:

\[\left(\sum\limits_{a_i=0}^{n} a_i \times \binom{n-a_i+m-2}{m-2}\right) \times j! \]

由于 \(a_i=0\) 的时候没有值,所以 \(a_i\) 的初始值可以为 \(1\)。发现对于每一个 \(j\),前面的式子是一样的,所以可以将其变为:

\[\left(\sum\limits_{a_i=1}^{n} a_i \times \binom{n-a_i+m-2}{m-2}\right) \times \left(\sum\limits_{j=1}^{m}j!\right) \]

而前面的式子可以枚举每个 \(a_i\) 进行求解,后面可以直接预处理。

注意:

  • 求组合数的时候记得用 Lucas,因为如果直接求组合数,则求乘法逆元的时候,分母的阶乘有可能是 \(p\) 的倍数,此时就会返回 \(0\),而 Lucas 则保证 \(x,y<p\),所以 \(x,y\) 的阶乘也一定不是 \(p\) 的倍数,此时求组合数就不会出问题。

  • 阶乘的初始值要从 \(0\) 开始赋值,即 \(fact_0\) 要赋值为 \(1\),因为 \(\binom{n}{n}\) 等于 \(1\) 而不是 \(0\)

AcCode

#include <bits/stdc++.h>
using namespace std;
#define int long long

const int N=2e6+10; 

int n,m,p,ans1,ans2;
int fact[N];

inline int read(){
	int t=0,f=1;
	register char c=getchar();
	while(c<'0'||c>'9') f=(c=='-')?(-1):(f),c=getchar();
	while(c>='0'&&c<='9') t=(t<<3)+(t<<1)+(c^48),c=getchar();
	return t*f;
}

void solution(){
	/*
		将 n-i 个元素分到 m-1 组中
		每组可以为空
		有 n-i+m-1 个元素,插 m-2 个板
		有 n-i+m-2 个空隙
		ans=C_{n-i+m-2}^{m-2}
		
		对于第 j 组,每组答案为:
		i*C_{n-i+m-2}^{m-2} (i ∈ [1,n])  *   j!
		
		对于前面的式子,用 O(n) 求出
		后面的预处理得到 
		
		最后的答案为:
		cgm(i*C_{n-i+m-2}^{m-2}) * cgm(j!)    (i∈[1,n] j∈[1,m])  
	*/
}

int ksm(int x,int y){
	int sum=1;
	while(y){
		if(y&1) sum=sum*x%p;
		x=x*x%p;
		y>>=1;
	}
	return sum;
}

int C(int x,int y){
	if(x<y) return 0;
	return fact[x]*ksm(fact[x-y],p-2)%p*ksm(fact[y],p-2)%p;
}

int lucas(int x,int y){
	if(y==0) return 1;
	return C(x%p,y%p)*lucas(x/p,y/p)%p;
}

void init(){
	fact[0]=1;
	for(int i=1;i<=n+m+2;i++) fact[i]=fact[i-1]*i%p;
}

signed main(){
	n=read(),m=read(),p=read();
	if(m==1){cout<<n%p;return 0;}
	init();
	for(int i=1;i<=n;i++) ans1=(ans1+i*lucas(n-i+m-2,m-2)%p)%p;
	for(int i=1;i<=m;i++) ans2=(ans2+fact[i])%p;
	cout<<ans1*ans2%p;
	return 0;
}

posted @ 2025-03-27 10:09  ask_silently  阅读(3)  评论(0)    收藏  举报