现在的位置: 首页 > 综合 > 正文

1211: [HNOI2004]树的计数 (prufer编码,排列组合,质因数分解)

2018年04月24日 ⁄ 综合 ⁄ 共 1028字 ⁄ 字号 评论关闭

明明的烦恼简化版。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#define inf 0x7fffffff
#define ll long long
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,tot,cnt,d[151],num[151],pri[151];
ll s[25],ans=1;
inline bool jud(int x){
	for(int i=2;i<=sqrt(x);++i)
		if(x%i==0)return 0;
	return 1;
}
inline void getpri(){
	for(int i=2;i<=150;++i)
		if(jud(i))pri[++cnt]=i;
}
inline void getfac(){
	s[1]=1;
	for(int i=2;i<=22;++i)
		s[i]=s[i-1]*i;
}
inline void solve(ll x,int f){
	for(int i=1;i<=cnt;++i){
		if(x<=1)return;
		while(x%pri[i]==0){
			num[i]+=f;
			x/=pri[i];
		}
	}
}
int main(){
	getfac();
	getpri();
	n=read();
	if(n==1){
		int x=read();
		if(!x)printf("1");
		else printf("0");
		return 0;
	}
	for(int i=1;i<=n;++i){
		d[i]=read();
		if(!d[i]){printf("0");return 0;}
		tot+=--d[i];
	}
	if(tot!=n-2){printf("0");return 0;}
	solve(s[n-2],1);
	for(int i=1;i<=n;++i)
		solve(s[d[i]],-1);
	for(int i=1;i<=cnt;++i)
		while(num[i]--)
			ans*=pri[i];
	printf("%lld",ans);
	return 0;
}

抱歉!评论已关闭.