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;  
}  
View Code

 

posted @ 2017-02-28 18:16  free-loop  阅读(193)  评论(0编辑  收藏  举报