luogu P2290 [HNOI2004]树的计数
Posted 275307894a
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P2290 [HNOI2004]树的计数相关的知识,希望对你有一定的参考价值。
题面传送门
首先这种生成树计数想到Prufer序列。
然后因为度数为\\(d_i\\)的点会在Prufer序列中出现\\(d_i-1\\)次所以直接重排列公式即可。
然而这个没有模数什么的。
于是就要分解完质因数后再乘。
时间复杂度\\(O(nlogn)\\)
code:
#include <vector>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<set>
#include<map>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 150
#define M 100000
#define eps (1e-5)
#define mod (1<<31)
#define U unsigned int
using namespace std;
int n,x,A[N+5],G[N+5],fl[N+5],pre[N+5],pr[N+5],ph,ToT; ll Ans=1;
int main(){
freopen("1.in","r",stdin);
re int i,j;scanf("%d",&n);if(n==1){scanf("%d",&x);printf("%d\\n",x?0:1);return 0;}
A[n-2]++;for(i=2;i<=n;i++){
!fl[i]&&(pr[++ph]=i,pre[i]=i);for(j=1;j<=ph&&pr[j]*i<=n;j++){fl[pr[j]*i]=1;pre[pr[j]*i]=pr[j];if(i%pr[j]==0) break;}
}
for(i=1;i<=n;i++){scanf("%d",&x),A[x-1]--,ToT+=x;if(!x){printf("0\\n");return 0;}}if(ToT!=2*n-2){printf("0\\n");return 0;}
for(i=n;i;i--) A[i]+=A[i+1];
for(i=1;i<=n;i++){x=i;while(x^1)G[pre[x]]+=A[i],x/=pre[x];}
for(i=1;i<=n;i++) while(G[i]--) Ans*=i;printf("%d\\n",Ans);
}
以上是关于luogu P2290 [HNOI2004]树的计数的主要内容,如果未能解决你的问题,请参考以下文章