【BZOJ1005】[HNOI2008]明明的烦恼(prufer序列)

【BZOJ1005】[HNOI2008]明明的烦恼(prufer序列)

题面

BZOJ
洛谷

题解

戳这里

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 1010
inline int read()
{
    int x=0;bool t=false;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}
const int yw=10000;
struct BigNum
{
    ll s[MAX*2];int ws;
    void output()
        {
            printf("%lld",s[ws]);
            for(int i=ws-1;i;--i)
                printf("%04lld",s[i]);
            puts("");
        }
    void clear(){memset(s,0,sizeof(s));ws=0;}
}ans;
BigNum operator*(BigNum a,int b)
{
    int ws=a.ws;BigNum ret;ret.clear();
    for(int i=1;i<=ws;++i)ret.s[i]=a.s[i]*b;
    for(int i=1;i<=ws;++i)ret.s[i+1]+=ret.s[i]/yw,ret.s[i]%=yw;
    while(ret.s[ws+1])++ws,ret.s[ws+1]+=ret.s[ws]/yw,ret.s[ws]%=yw;
    ret.ws=ws;return ret;
}
int sum,a[MAX],cnt,n;
int p1[MAX],p2[MAX];
void add(int *p,int x)
{
    for(int i=2;i*i<=x;++i)
        while(x%i==0)x/=i,++p[i];
    if(x>1)++p[x];
}
int main()
{
    n=read();
    for(int i=1;i<=n;++i)
    {
        a[i]=read();if(a[i]==-1)continue;
        ++cnt;sum+=a[i]-1;
    }
    if(sum+n>2*(n-1)){puts("0");return 0;}
    for(int i=n-2;i;--i)add(p1,i);
    for(int i=n-2-sum;i;--i)add(p2,i);
    for(int i=1;i<=n;++i)
        if(a[i]!=-1)
            for(int j=1;j<a[i];++j)
                add(p2,j);
    for(int i=1;i<=n-2-sum;++i)add(p1,n-cnt);
    for(int i=1;i<=n;++i)p1[i]-=p2[i];
    ans.s[1]=1;ans.ws=1;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=p1[i];++j)
            ans=ans*i;
    ans.output();
    return 0;           
}

猜你喜欢

转载自www.cnblogs.com/cjyyb/p/9715800.html