BZOJ 1005 明明的烦恼(prufer序列+高精度)
有一种东西叫树的prufer序列,一个树的与一个prufer序列是一一对应的关系。
设有m个度数确定的点,这些点的度为dee[i],那么每个点在prufer序列中出现了dee[i]-1次。
由排列组合可以推出公式。需要用高精度。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 1100 using namespace std; typedef long long ll; struct abcd{ ll xx[400]; int cnt; abcd(int x=0) { memset(xx,0,sizeof xx); xx[1]=x; cnt=1; } ll& operator [] (int x) { return xx[x]; } }ans(1); abcd operator *= (abcd &x,abcd &y) { int i,j; abcd z; for(i=1;i<=x.cnt;i++) for(j=1;j<=y.cnt;j++) z[i+j-1]+=x[i]*y[j],z[i+j]+=z[i+j-1]/100000000,z[i+j-1]%=100000000; z.cnt=x.cnt+y.cnt; if(!z[z.cnt]) --z.cnt; x=z; } ostream& operator << (ostream& os,abcd &x) { int i; printf("%lld",x[x.cnt]); for(i=x.cnt-1;i;i--) printf("%08lld",x[i]); return os; } int n,m,remain,cnt[M],stack[M],top; void Decomposition(int x,int y) { int i; for(i=2;i*i<=x;i++) while(x%i==0) cnt[i]+=y,x/=i; if(x^1) cnt[x]+=y; } void Quick_Power(int i,int y) { abcd x(i); while(y) { if(y&1)ans*=x; x*=x; y>>=1; } } int main() { int i,x; cin>>n;remain=n-2; for(i=1;i<=n;i++) { scanf("%d",&x); if(x==-1) ++m; else if(x>1) stack[++top]=x-1,remain-=x-1; } for(i=2;i<=n-2;i++) Decomposition(i,1); while(top) { for(i=2;i<=stack[top];i++) Decomposition(i,-1); stack[top--]=0; } for(i=2;i<=remain;i++) Decomposition(i,-1); Decomposition(m,remain); for(i=1;i<=n;i++) if(cnt[i]) Quick_Power(i,cnt[i]); cout<<ans<<endl; }