一道十分显然的prufer序列题
有个点的度数是确定的,方案数为,其中
此时还有个点的度数不确定,它们可以任意排列在剩下的位置上,所以答案就是
化简为
数据很大,高精度除法又太麻烦,所以用了质因数分解
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e3+5,maxl=3e3+5;
int n,cnt,tot,sum,d[maxn],p[maxn];bool vis[maxn];
struct LLL{
int len,a[maxl];
LLL(){len=1;memset(a,0,sizeof(a));}
LLL(int x){
len=0;memset(a,0,sizeof(a));
while(x) a[++len]=x%10,x/=10;
}
void print(){for(int i=len;i;i--) printf("%d",a[i]);}
LLL operator*(const LLL&b){
LLL ret;
ret.len=len+b.len-1;
for(int i=1;i<=len;i++)
for(int j=1;j<=b.len;j++){
ret.a[i+j-1]+=a[i]*b.a[j];
}
for(int i=1;i<=ret.len;i++){
ret.a[i+1]+=ret.a[i]/10;
ret.a[i]%=10;
}
if(ret.a[ret.len+1]) ret.len++;
while(ret.len>1&&!ret.a[ret.len]) ret.len--;
return ret;
}
}Ans;
struct ad{
int a[maxl];
ad(){memset(a,0,sizeof(a));}
ad(int x){
memset(a,0,sizeof(a));
for(int i=1;i<=tot;i++){
while(x%p[i]==0) x/=p[i],a[i]++;
if(x==1) break;
}
}
ad operator*(const ad&b){
ad ret;
for(int i=1;i<=tot;i++) ret.a[i]=a[i]+b.a[i];
return ret;
}
ad operator/(const ad&b){
ad ret;
for(int i=1;i<=tot;i++) ret.a[i]=a[i]-b.a[i];
return ret;
}
}ANS,fac[maxn];
inline int read(){
int ret=0,fh=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')fh=-fh;ch=getchar();}
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*fh;
}
LLL pow(int x,int y){
LLL ret=1,t=x;
while(y){
if(y&1) ret=ret*t;
t=t*t,y>>=1;
}
return ret;
}
int main(){
freopen("P1005.in","r",stdin);
freopen("P1005.out","w",stdout);
n=read();
vis[0]=vis[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]) p[++tot]=i;
for(int j=1;i*p[j]<=n&&j<=tot;j++){
vis[i*p[j]]=1;
if(i%p[j]==0) break;
}
}
for(int i=1;i<=n;i++){
int x=read();
if(x==0){printf("0\n");return 0;}
if(x!=-1) d[++cnt]=x,sum+=(x-1);
}
if(sum>n-2){printf("0\n");return 0;}
for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i;
ad tp=n-cnt;
for(int i=1,ti=n-sum-2;i<=ti;i++) ANS=ANS*tp;
ANS=ANS*fac[n-2];
ANS=ANS/fac[n-sum-2];
for(int i=1;i<=cnt;i++) ANS=ANS/fac[d[i]-1];
Ans=1;
for(int i=1;i<=tot;i++){
LLL x=pow(p[i],ANS.a[i]);
Ans=Ans*x;
}
Ans.print();
return 0;
}