题目传送门
。。。
解法:
卡了一天。。
原来是高精度数组开小了???
其实就是组合嘛。
假设cnt为-1的个数。
sum为各个规定的度数-1的和。
那么首先在一个n-2的prufer数列里面。
有sum个位置被确定了。
首先就是n-2里选sum。
然后sum个可以进行排列。
那么乘sum的阶乘。
但是里面会有重复。
所以需要除以每个(d[i]-1)的阶乘。
这里我用的是分解质因数。跟上一题一样的原理。
最后还剩下n-2-sum个位置,每个位置有cnt种选择。
所以最后乘cnt的(n-2-sum)次方就好。
代码实现:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
int d[1100],pr[1100],cnt[1100];
bool pd(int x) {
if(x<=1)return false;
int t=int(sqrt(double(x+1)));
for(int i=2;i<=t;i++)if(x%i==0)return false;
return true;
}
struct node {int len,a[11000];node() {len=0;memset(a,0,sizeof(a));}};
node chengfa(node n1,node n2) {
node no;no.len=n1.len+n2.len-1;
for(int i=1;i<=n1.len;i++)for(int j=1;j<=n2.len;j++)no.a[i+j-1]+=n1.a[i]*n2.a[j];
for(int i=1;i<=no.len;i++) {no.a[i+1]+=no.a[i]/10;no.a[i]%=10;}
int i=no.len;while(no.a[i+1]>0) {i++;no.a[i+1]+=no.a[i]/10;no.a[i]%=10;}no.len=i;
return no;
}
node turn(int x) {node no;while(x!=0) {no.len++;no.a[no.len]=x%10;x/=10;}return no;}
node pow_mod(node a,int b) {
node ans;ans.len=1;ans.a[1]=1;
while(b!=0) {if(b%2==1)ans=chengfa(ans,a);a=chengfa(a,a);b/=2;}
return ans;
}
int main() {
//freopen("tree2.in","r",stdin);
int n,s=0,sum=0;scanf("%d",&n);
for(int i=1;i<=n;i++) {scanf("%d",&d[i]);if(d[i]==-1)s++;else sum+=d[i]-1;}
if(sum>n-2) {printf("0\n");return 0;}
if(sum<n-2&&s==0) {printf("0\n");return 0;}
if(n==1&&d[1]>=1) {printf("0\n");return 0;}
if(n==1) {printf("1\n");return 0;}
for(int i=1;i<=n;i++)if(d[i]==0&&n!=1) {printf("0\n");return 0;}
if(n==2){
if((d[1]==0||d[1]>1)||(d[2]==0||d[2]>1)) printf("0\n");
else printf("1\n");
return 0;
}
int len=0;for(int i=1;i<=n;i++)if(pd(i)==true)pr[++len]=i;
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=sum;i++) {
int x=(n-2)-i+1;
for(int j=1;j<=len;j++) {
if(pr[j]>x)break;
while(x%pr[j]==0&&x!=0) {cnt[j]++;x/=pr[j];}
}
}
for(int i=1;i<=n;i++) {
if(d[i]==-1)continue;
for(int k=2;k<=d[i]-1;k++) {
int x=k;
for(int j=1;j<=len;j++) {
if(pr[j]>x)break;
while(x%pr[j]==0&&x!=0) {cnt[j]--;x/=pr[j];}
}
}
}
node ans;ans.len=1;ans.a[1]=1;
for(int i=1;i<=len;i++)ans=chengfa(ans,pow_mod(turn(pr[i]),cnt[i]));
node t=turn(s);ans=chengfa(ans,pow_mod(t,n-2-sum));
for(int i=ans.len;i>=1;i--)printf("%d",ans.a[i]);printf("\n");
return 0;
}