您的位置:首页 > Web前端

bzoj1005(prufer+组合+高精度)

2016-03-27 10:22 316 查看

1005: [HNOI2008]明明的烦恼

Time Limit: 1 Sec Memory Limit: 162 MB

Submit: 3731 Solved: 1489

[Submit][Status][Discuss]

Description

自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?

Input

第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1

Output

一个整数,表示不同的满足要求的树的个数,无解输出0

Sample Input

3

1

-1

-1

Sample Output

2

HINT

两棵树分别为1-2-3;1-3-2

解题思路:
简单的prufer+组合数学,唯独恶心的高精度



#include<cstdio>

#include<cstring>

#include<algorithm>

#include<iostream>

using namespace std;

int n,tail,len2,sug,sum,pos;

int dui[10005],q[10005],so[10005];

int h1[10005],ans[10005],c[100005];

int a[100001],gg[100001];

inline int read()

{

char y; int x=0,f=1; y=getchar();

while (y<'0' || y>'9') {if (y=='-') f=-1; y=getchar();}

while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}

return f*x;

}

void solve()

{

bool bb[10001]; int len=0;

memset(bb,true,sizeof(bb));

for (int i=2;i<=10001;++i)

{

if (bb[i]==true)

{

++len; gg[len]=i; bb[i]=false;

for (int j=i;j<=10001;j+=i)

{

bb[j]=false;

}

}

}

}

void jud(int zhi,int pan)

{

if (zhi==0 || zhi==1) return;

int u=gg[1]; int og=1;

while (zhi/u!=0)

{

int sum=0;

int g=zhi;

int opp=u;

while (g/opp!=0)

{

sum+=g/opp; opp=opp*u;

}

if (dui[u]==0)

{

++tail; q[tail]=u; dui[u]=tail; so[tail]+=pan*sum;

}else so[dui[u]]+=pan*sum;

++og; u=gg[og];

}

}

void mul(int x)

{

memset(c,0,sizeof(c));

int len1=0;

while (x!=0)

{

++len1; h1[len1]=x%10; x=x/10;

}

for (int i=1;i<=len2;++i)

{

int u=0;

for (int j=1;j<=len1;++j)

{

c[i+j-1]=c[i+j-1]+u+ans[i]*h1[j];

u=c[i+j-1]/10;

c[i+j-1]%=10;

}

c[i+len1]+=u;

}

int len3=len2+len1;

while (c[len3]==0 && len3>1) --len3;

for (int i=1;i<=len3;++i)

ans[i]=c[i];

len2=len3;

}

int main()

{

solve();

n=read(); sug=0; sum=n-2; pos=0;

if (sum<sug)

{

cout<<"0";

return 0;

}

len2=1; ans[1]=1;

for (int i=1;i<=n;++i)

{

a[i]=read();

if (a[i]==-1)

++pos;else

{

sug+=a[i]-1; jud(a[i]-1,-1);

}

--a[i];

}

jud(sum,1); jud(sum-sug,-1);

for (int i=1;i<=tail;++i)

{

for (int j=1;j<=so[i];++j)

{

mul(q[i]);

}

}

for (int i=1;i<=sum-sug;++i)

{

mul(pos);

}

for (int i=len2;i>=1;--i)

printf("%d",ans[i]);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: