裸的prufer结论。
给个小链接prufer序列 ,里面有一个性质4就是本题答案,严谨证明可以上网找一找,如果从多组组合角度理解也可以。
剩下的就是特判,n==1时,du==0,1个,du!=0,废了。有du==0,废了。度数和大于(还是不等于来着?)2*(n-1),废了。拿到67分……。
接着就是求那个式子了,我有一套O(n)拆一个阶乘的理论。那这个就是O(n^2)了呗。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<vector> #include<queue> #include<stack> #include<set> #include<map> #define ll long long using namespace std; ll ans=1,n,du[250],sum,prime[300],prime_num; bool v[350]; ll read(){ ll sum=0;int f=1;char x=getchar(); while(x<'0'||x>'9'){ if(x=='-') f=-1; x=getchar(); }while(x>='0'&&x<='9'){ sum=sum*10+x-'0'; x=getchar(); }return sum*f; } void doprime(int x){ for(int i=2;i<=x;i++){ if(!v[i]) prime[++prime_num]=i; for(int j=1;j<=prime_num&&i*prime[j]<=x;j++){ v[i*prime[j]]=1; if(i%prime[j]==0) break; } } } ll qpow(ll x,ll k){ ll ans=1; for(;k;k>>=1,x=x*x) if(k&1) ans=ans*x; return ans; } int main(){ n=read(); if(n==1){ du[1]=read(); if(!du[1]) puts("1"); else puts("0"); return 0; } for(int i=1;i<=n;i++){ du[i]=read(); if(!du[i]){ puts("0"); return 0; } sum+=du[i]; } if(sum!=2*(n-1)){ puts("0"); return 0; } doprime(n); for(int i=1;i<=prime_num;i++){ int s=0; for(int j=n-2;j/=prime[i];) s+=j; for(int j=1;j<=n;j++) for(int k=du[j]-1;k/=prime[i];) s-=k; ans=ans*qpow(prime[i],s); }printf("%lld",ans); return 0; }View Code