D. Counting Factorizations (dp 组合数学)

链接:https://codeforces.com/contest/1794/problem/D
题意:给定2n个数,要求选n个互不相同的素数作质因数分解的底数,剩余n个数作指数,问能表示多少不同的数。
n<=2022 a[i]<=1e6
题解:容易想到选完素数后,答案是多重组合n!/(r1!r2!r3!...),其中ri表示某个数的个数,注意到显然当素数个数<n时为0,故我们只考虑素数个数>=n的情况。
对于所有非素数,显然其ri不会变化,对于素数,其值为ri(未被选择)或ri-1(被选择),故答案的一部分n!/(r1!...rk!)不变(非素数部分),对于变化的部分,1/(ri!...rj!)(素数部分)的所有和可以用dp做(只有-1和-0两种情况,可转移),令f(i,j)表示前i个素数中j个数被选的所有可能和,f(i,j)=f(i-1,j)1/ri!+f(i-1,j-1)1/(ri-1)!,预处理阶乘和阶乘的逆元即可O(n2)得到答案。
代码:

#define int long long
using namespace std;
const int N=5010,mod=998244353,M=1e6+100;
int w[N],c[N],a[N],p[M],fac[M],f[N][N],v[M],cnt[M],inv[M];
int qpow(int x,int y){
	int ans=1;
	while(y){
		if(y&1) ans=ans*x%mod;
		x=x*x%mod;
		y>>=1;
	}
	return ans;
}
int m;
bool primes(int x){
	if(x==1) return false;
	for(int i=2;i*i<=x;i++){
		if(x%i==0) return false;
	}
	return true;
}
int invv(int x){
	return qpow(x,mod-2);
}
void init(){
	fac[0]=1;
	for(int i=1;i<=1e6+10;i++){
		fac[i]=fac[i-1]*i%mod;
	}
	inv[0]=1;
	inv[1]=1;
	for(int i=2;i<=1e6+10;i++){
		inv[i]=invv(fac[i]);
	}
}

signed main(){
	init();
	int n;cin>>n;
	int k=0,t=0;
	for(int i=1;i<=n+n;i++) cin>>a[i];
//	sort(a+1,a+n+n+1);
	for(int i=1;i<=n+n;i++){
		if(!primes(a[i])){
			cnt[a[i]]++;
			if(cnt[a[i]]==1){
				w[++k]=a[i];
			}
		}
		else{
			cnt[a[i]]++;
			if(cnt[a[i]]==1)
			c[++t]=a[i];
		}
	}
	if(t<n){
		cout<<0;
		return 0;
	}
	int res=fac[n];
	for(int i=1;i<=k;i++){
		res=res*inv[cnt[w[i]]]%mod;
	}
	f[0][0]=1;
	for(int i=1;i<=t;i++){
		f[i][0]=f[i-1][0]*inv[cnt[c[i]]]%mod;
		for(int j=1;j<=min(n,i);j++){
			f[i][j]=(f[i-1][j]*inv[cnt[c[i]]]%mod+f[i-1][j-1]*inv[cnt[c[i]]-1]%mod)%mod;
		}
	}
	res=res*f[t][n]%mod;
	cout<<res;
}
posted @   wrong,anser  阅读(96)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示