博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
省选专练之【HNOI2004】树的计数
阅读量:4922 次
发布时间:2019-06-11

本文共 14687 字,大约阅读时间需要 48 分钟。

一个有n个结点的树,设它的结点分别为v1, v2, …, vn,已知第i个结点vi的度数为di,问满足这样的条件的不同的树有多少棵。 

给定n,d1, d2, …, dn,编程需要输出满足d(vi)=di的树的个数。

第一行是一个正整数n,表示树有n个结点。第二行有n个数,第i个数表示di,即树的第i个结点的度数。其中1<=n<=150,输入数据保证满足条件的树超过10^17个。

我们知道n阶完全图的生成树个数是N^{N-2}所以先求个这个

但是由于在排列中会存在重复,固定度数的会多算,因为对于他们来说排列是没有意义的

所以除以他们的限制

但是不得house的出题人神奇的出了一个高精度

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define LL long long#define DIGIT 4 //ËÄλ¸ô¿ª,¼´Íò½øÖÆ #define DEPTH 10000 //Íò½øÖÆ #define MAX 10000 typedef int bignum_t[MAX+1]; /************************************************************************/ /* ¶ÁÈ¡²Ù×÷Êý£¬¶Ô²Ù×÷Êý½øÐд¦Àí´æ´¢ÔÚÊý×éÀï */ /************************************************************************/ int read(bignum_t a,istream&is=cin) { char buf[MAX*DIGIT+1],ch ; int i,j ; memset((void*)a,0,sizeof(bignum_t)); if(!(is>>buf))return 0 ; for(a[0]=strlen(buf),i=a[0]/2-1;i>=0;i--) ch=buf[i],buf[i]=buf[a[0]-1-i],buf[a[0]-1-i]=ch ; for(a[0]=(a[0]+DIGIT-1)/DIGIT,j=strlen(buf);j
1;a[0]--); return 1 ; } void write(const bignum_t a,ostream&os=cout) { int i,j ; for(os<
=DEPTH;c[c[0]+1]=c[c[0]]/DEPTH,c[c[0]]%=DEPTH,c[0]++); return comp(a,c); } int comp(const bignum_t a,const int c,const int d,const bignum_t b) { int i,t=0,O=-DEPTH*2 ; if(b[0]-a[0]
d;i--) { t=t*DEPTH+a[i-d]*c-b[i]; if(t>0)return 1 ; if(t
0)return 1 ; if(t
0 ; } /************************************************************************/ /* ´óÊýÓë´óÊýÏà¼Ó */ /************************************************************************/ void add(bignum_t a,const bignum_t b) { int i ; for(i=1;i<=b[0];i++) if((a[i]+=b[i])>=DEPTH) a[i]-=DEPTH,a[i+1]++; if(b[0]>=a[0]) a[0]=b[0]; else for(;a[i]>=DEPTH&&i
0); } /************************************************************************/ /* ´óÊýÓëСÊýÏà¼Ó */ /************************************************************************/ void add(bignum_t a,const int b) { int i=1 ; for(a[1]+=b;a[i]>=DEPTH&&i
=DEPTH;a[a[0]+1]=a[a[0]]/DEPTH,a[a[0]]%=DEPTH,a[0]++); } /************************************************************************/ /* ´óÊýÏà¼õ(±»¼õÊý>=¼õÊý) */ /************************************************************************/ void sub(bignum_t a,const bignum_t b) { int i ; for(i=1;i<=b[0];i++) if((a[i]-=b[i])<0) a[i+1]--,a[i]+=DEPTH ; for(;a[i]<0;a[i]+=DEPTH,i++,a[i]--); for(;!a[a[0]]&&a[0]>1;a[0]--); } /************************************************************************/ /* ´óÊý¼õȥСÊý(±»¼õÊý>=¼õÊý) */ /************************************************************************/ void sub(bignum_t a,const int b) { int i=1 ; for(a[1]-=b;a[i]<0;a[i+1]+=(a[i]-DEPTH+1)/DEPTH,a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH,i++); for(;!a[a[0]]&&a[0]>1;a[0]--); } void sub(bignum_t a,const bignum_t b,const int c,const int d) { int i,O=b[0]+d ; for(i=1+d;i<=O;i++) if((a[i]-=b[i-d]*c)<0) a[i+1]+=(a[i]-DEPTH+1)/DEPTH,a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH ; for(;a[i]<0;a[i+1]+=(a[i]-DEPTH+1)/DEPTH,a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH,i++); for(;!a[a[0]]&&a[0]>1;a[0]--); } /************************************************************************/ /* ´óÊýÏà³Ë£¬¶ÁÈë±»³ËÊýa£¬³ËÊýb£¬½á¹û±£´æÔÚc[] */ /************************************************************************/ void mul(bignum_t c,const bignum_t a,const bignum_t b) { int i,j ; memset((void*)c,0,sizeof(bignum_t)); for(c[0]=a[0]+b[0]-1,i=1;i<=a[0];i++) for(j=1;j<=b[0];j++) if((c[i+j-1]+=a[i]*b[j])>=DEPTH) c[i+j]+=c[i+j-1]/DEPTH,c[i+j-1]%=DEPTH ; for(c[0]+=(c[c[0]+1]>0);!c[c[0]]&&c[0]>1;c[0]--); } /************************************************************************/ /* ´óÊý³ËÒÔСÊý£¬¶ÁÈë±»³ËÊýa£¬³ËÊýb£¬½á¹û±£´æÔÚ±»³ËÊý */ /************************************************************************/ void mul(bignum_t a,const int b) { int i ; for(a[1]*=b,i=2;i<=a[0];i++) { a[i]*=b ; if(a[i-1]>=DEPTH) a[i]+=a[i-1]/DEPTH,a[i-1]%=DEPTH ; } for(;a[a[0]]>=DEPTH;a[a[0]+1]=a[a[0]]/DEPTH,a[a[0]]%=DEPTH,a[0]++); for(;!a[a[0]]&&a[0]>1;a[0]--); } void mul(bignum_t b,const bignum_t a,const int c,const int d) { int i ; memset((void*)b,0,sizeof(bignum_t)); for(b[0]=a[0]+d,i=d+1;i<=b[0];i++) if((b[i]+=a[i-d]*c)>=DEPTH) b[i+1]+=b[i]/DEPTH,b[i]%=DEPTH ; for(;b[b[0]+1];b[0]++,b[b[0]+1]=b[b[0]]/DEPTH,b[b[0]]%=DEPTH); for(;!b[b[0]]&&b[0]>1;b[0]--); } /**************************************************************************/ /* ´óÊýÏà³ý,¶ÁÈë±»³ýÊýa£¬³ýÊýb£¬½á¹û±£´æÔÚc[]Êý×é */ /* ÐèÒªcomp()º¯Êý */ /**************************************************************************/ void div(bignum_t c,bignum_t a,const bignum_t b) { int h,l,m,i ; memset((void*)c,0,sizeof(bignum_t)); c[0]=(b[0]
>1;h>l;m=(h+l+1)>>1) if(comp(b,m,i-1,a))h=m-1 ; else l=m ; for(;!c[c[0]]&&c[0]>1;c[0]--); c[0]=c[0]>1?c[0]:1 ; } void div(bignum_t a,const int b,int&c) { int i ; for(c=0,i=a[0];i;c=c*DEPTH+a[i],a[i]=c/b,c%=b,i--); for(;!a[a[0]]&&a[0]>1;a[0]--); } /************************************************************************/ /* ´óÊýƽ·½¸ù£¬¶ÁÈë´óÊýa£¬½á¹û±£´æÔÚb[]Êý×éÀï */ /* ÐèÒªcomp()º¯Êý */ /************************************************************************/ void sqrt(bignum_t b,bignum_t a) { int h,l,m,i ; memset((void*)b,0,sizeof(bignum_t)); for(i=b[0]=(a[0]+1)>>1;i;sub(a,b,m,i-1),b[i]+=m,i--) for(h=DEPTH-1,l=0,b[i]=m=(h+l+1)>>1;h>l;b[i]=m=(h+l+1)>>1) if(comp(b,m,i-1,a))h=m-1 ; else l=m ; for(;!b[b[0]]&&b[0]>1;b[0]--); for(i=1;i<=b[0];b[i++]>>=1); } /************************************************************************/ /* ·µ»Ø´óÊýµÄ³¤¶È */ /************************************************************************/ int length(const bignum_t a) { int t,ret ; for(ret=(a[0]-1)*DIGIT,t=a[a[0]];t;t/=10,ret++); return ret>0?ret:1 ; } /************************************************************************/ /* ·µ»ØÖ¸¶¨Î»ÖõÄÊý×Ö£¬´ÓµÍλ¿ªÊ¼Êýµ½µÚb룬·µ»ØbλÉϵÄÊý */ /************************************************************************/ int digit(const bignum_t a,const int b) { int i,ret ; for(ret=a[(b-1)/DIGIT+1],i=(b-1)%DIGIT;i;ret/=10,i--); return ret%10 ; } /************************************************************************/ /* ·µ»Ø´óÊýĩβ0µÄ¸öÊý */ /************************************************************************/ int zeronum(const bignum_t a) { int ret,t ; for(ret=0;!a[ret+1];ret++); for(t=a[ret+1],ret*=DIGIT;!(t%10);t/=10,ret++); return ret ; } void comp(int*a,const int l,const int h,const int d) { int i,j,t ; for(i=l;i<=h;i++) for(t=i,j=2;t>1;j++) while(!(t%j)) a[j]+=d,t/=j ; } void convert(int*a,const int h,bignum_t b) { int i,j,t=1 ; memset(b,0,sizeof(bignum_t)); for(b[0]=b[1]=1,i=2;i<=h;i++) if(a[i]) for(j=a[i];j;t*=i,j--) if(t*i>DEPTH) mul(b,t),t=1 ; mul(b,t); } #define SGN(x) ((x)>0?1:((x)<0?-1:0)) #define ABS(x) ((x)>0?(x):-(x)) int read(bignum_t a,int&sgn,istream&is=cin) { char str[MAX*DIGIT+2],ch,*buf ; int i,j ; memset((void*)a,0,sizeof(bignum_t)); if(!(is>>str))return 0 ; buf=str,sgn=1 ; if(*buf=='-')sgn=-1,buf++; for(a[0]=strlen(buf),i=a[0]/2-1;i>=0;i--) ch=buf[i],buf[i]=buf[a[0]-1-i],buf[a[0]-1-i]=ch ; for(a[0]=(a[0]+DIGIT-1)/DIGIT,j=strlen(buf);j
1;a[0]--); if(a[0]==1&&!a[1])sgn=0 ; return 1 ; } struct bignum { bignum_t num ; int sgn ; public : inline bignum() { memset(num,0,sizeof(bignum_t)); num[0]=1 ; sgn=0 ; } inline int operator!() { return num[0]==1&&!num[1]; } inline bignum&operator=(const bignum&a) { memcpy(num,a.num,sizeof(bignum_t)); sgn=a.sgn ; return*this ; } inline bignum&operator=(const int a) { memset(num,0,sizeof(bignum_t)); num[0]=1 ; sgn=SGN (a); add(num,sgn*a); return*this ; } ; inline bignum&operator+=(const bignum&a) { if(sgn==a.sgn)add(num,a.num); else if (sgn&&a.sgn) { int ret=comp(num,a.num); if(ret>0)sub(num,a.num); else if(ret<0) { bignum_t t ; memcpy(t,num,sizeof(bignum_t)); memcpy(num,a.num,sizeof(bignum_t)); sub (num,t); sgn=a.sgn ; } else memset(num,0,sizeof(bignum_t)),num[0]=1,sgn=0 ; } else if(!sgn) memcpy(num,a.num,sizeof(bignum_t)),sgn=a.sgn ; return*this ; } inline bignum&operator+=(const int a) { if(sgn*a>0)add(num,ABS(a)); else if(sgn&&a) { int ret=comp(num,ABS(a)); if(ret>0)sub(num,ABS(a)); else if(ret<0) { bignum_t t ; memcpy(t,num,sizeof(bignum_t)); memset(num,0,sizeof(bignum_t)); num[0]=1 ; add(num,ABS (a)); sgn=-sgn ; sub(num,t); } else memset(num,0,sizeof(bignum_t)),num[0]=1,sgn=0 ; } else if (!sgn)sgn=SGN(a),add(num,ABS(a)); return*this ; } inline bignum operator+(const bignum&a) { bignum ret ; memcpy(ret.num,num,sizeof (bignum_t)); ret.sgn=sgn ; ret+=a ; return ret ; } inline bignum operator+(const int a) { bignum ret ; memcpy(ret.num,num,sizeof (bignum_t)); ret.sgn=sgn ; ret+=a ; return ret ; } inline bignum&operator-=(const bignum&a) { if(sgn*a.sgn<0)add(num,a.num); else if (sgn&&a.sgn) { int ret=comp(num,a.num); if(ret>0)sub(num,a.num); else if(ret<0) { bignum_t t ; memcpy(t,num,sizeof(bignum_t)); memcpy(num,a.num,sizeof(bignum_t)); sub(num,t); sgn=-sgn ; } else memset(num,0,sizeof(bignum_t)),num[0]=1,sgn=0 ; } else if(!sgn)add (num,a.num),sgn=-a.sgn ; return*this ; } inline bignum&operator-=(const int a) { if(sgn*a<0)add(num,ABS(a)); else if(sgn&&a) { int ret=comp(num,ABS(a)); if(ret>0)sub(num,ABS(a)); else if(ret<0) { bignum_t t ; memcpy(t,num,sizeof(bignum_t)); memset(num,0,sizeof(bignum_t)); num[0]=1 ; add(num,ABS(a)); sub(num,t); sgn=-sgn ; } else memset(num,0,sizeof(bignum_t)),num[0]=1,sgn=0 ; } else if (!sgn)sgn=-SGN(a),add(num,ABS(a)); return*this ; } inline bignum operator-(const bignum&a) { bignum ret ; memcpy(ret.num,num,sizeof(bignum_t)); ret.sgn=sgn ; ret-=a ; return ret ; } inline bignum operator-(const int a) { bignum ret ; memcpy(ret.num,num,sizeof(bignum_t)); ret.sgn=sgn ; ret-=a ; return ret ; } inline bignum&operator*=(const bignum&a) { bignum_t t ; mul(t,num,a.num); memcpy(num,t,sizeof(bignum_t)); sgn*=a.sgn ; return*this ; } inline bignum&operator*=(const int a) { mul(num,ABS(a)); sgn*=SGN(a); return*this ; } inline bignum operator*(const bignum&a) { bignum ret ; mul(ret.num,num,a.num); ret.sgn=sgn*a.sgn ; return ret ; } inline bignum operator*(const int a) { bignum ret ; memcpy(ret.num,num,sizeof (bignum_t)); mul(ret.num,ABS(a)); ret.sgn=sgn*SGN(a); return ret ; } inline bignum&operator/=(const bignum&a) { bignum_t t ; div(t,num,a.num); memcpy (num,t,sizeof(bignum_t)); sgn=(num[0]==1&&!num[1])?0:sgn*a.sgn ; return*this ; } inline bignum&operator/=(const int a) { int t ; div(num,ABS(a),t); sgn=(num[0]==1&&!num [1])?0:sgn*SGN(a); return*this ; } inline bignum operator/(const bignum&a) { bignum ret ; bignum_t t ; memcpy(t,num,sizeof(bignum_t)); div(ret.num,t,a.num); ret.sgn=(ret.num[0]==1&&!ret.num[1])?0:sgn*a.sgn ; return ret ; } inline bignum operator/(const int a) { bignum ret ; int t ; memcpy(ret.num,num,sizeof(bignum_t)); div(ret.num,ABS(a),t); ret.sgn=(ret.num[0]==1&&!ret.num[1])?0:sgn*SGN(a); return ret ; } inline bignum&operator%=(const bignum&a) { bignum_t t ; div(t,num,a.num); if(num[0]==1&&!num[1])sgn=0 ; return*this ; } inline int operator%=(const int a) { int t ; div(num,ABS(a),t); memset(num,0,sizeof (bignum_t)); num[0]=1 ; add(num,t); return t ; } inline bignum operator%(const bignum&a) { bignum ret ; bignum_t t ; memcpy(ret.num,num,sizeof(bignum_t)); div(t,ret.num,a.num); ret.sgn=(ret.num[0]==1&&!ret.num [1])?0:sgn ; return ret ; } inline int operator%(const int a) { bignum ret ; int t ; memcpy(ret.num,num,sizeof(bignum_t)); div(ret.num,ABS(a),t); memset(ret.num,0,sizeof(bignum_t)); ret.num[0]=1 ; add(ret.num,t); return t ; } inline bignum&operator++() { *this+=1 ; return*this ; } inline bignum&operator--() { *this-=1 ; return*this ; } ; inline int operator>(const bignum&a) { return sgn>0?(a.sgn>0?comp(num,a.num)>0:1):(sgn<0?(a.sgn<0?comp(num,a.num)<0:0):a.sgn<0); } ; inline int operator>(const int a) { return sgn>0?(a>0?comp(num,a)>0:1):(sgn<0?(a<0?comp(num,-a)<0:0):a<0); } ; inline int operator>=(const bignum&a) { return sgn>0?(a.sgn>0?comp(num,a.num)>=0:1):(sgn<0?(a.sgn<0?comp(num,a.num)<=0:0):a.sgn<=0); } ; inline int operator>=(const int a) { return sgn>0?(a>0?comp(num,a)>=0:1):(sgn<0?(a<0?comp(num,-a)<=0:0):a<=0); } ; inline int operator<(const bignum&a) { return sgn<0?(a.sgn<0?comp(num,a.num)>0:1):(sgn>0?(a.sgn>0?comp(num,a.num)<0:0):a.sgn>0); } ; inline int operator<(const int a) { return sgn<0?(a<0?comp(num,-a)>0:1):(sgn>0?(a>0?comp(num,a)<0:0):a>0); } ; inline int operator<=(const bignum&a) { return sgn<0?(a.sgn<0?comp(num,a.num)>=0:1):(sgn>0?(a.sgn>0?comp(num,a.num)<=0:0):a.sgn>=0); } ; inline int operator<=(const int a) { return sgn<0?(a<0?comp(num,-a)>=0:1): (sgn>0?(a>0?comp(num,a)<=0:0):a>=0); } ; inline int operator==(const bignum&a) { return(sgn==a.sgn)?!comp(num,a.num):0 ; } ; inline int operator==(const int a) { return(sgn*a>=0)?!comp(num,ABS(a)):0 ; } ; inline int operator!=(const bignum&a) { return(sgn==a.sgn)?comp(num,a.num):1 ; } ; inline int operator!=(const int a) { return(sgn*a>=0)?comp(num,ABS(a)):1 ; } ; inline int operator[](const int a) { return digit(num,a); } ; friend inline istream&operator>>(istream&is,bignum&a) { read(a.num,a.sgn,is); return is ; } ; friend inline ostream&operator<<(ostream&os,const bignum&a) { if(a.sgn<0) os<<'-' ; write(a.num,os); return os ; } ; friend inline bignum sqrt(const bignum&a) { bignum ret ; bignum_t t ; memcpy(t,a.num,sizeof(bignum_t)); sqrt(ret.num,t); ret.sgn=ret.num[0]!=1||ret.num[1]; return ret ; } ; friend inline bignum sqrt(const bignum&a,bignum&b) { bignum ret ; memcpy(b.num,a.num,sizeof(bignum_t)); sqrt(ret.num,b.num); ret.sgn=ret.num[0]!=1||ret.num[1]; b.sgn=b.num[0]!=1||ret.num[1]; return ret ; } ; inline int length() { return :: length(num); } ; inline int zeronum() { return :: zeronum(num); } ; }ans;bignum C(bignum n,bignum m){ ans=1;bignum maxx=n-m; for(int i=1;maxx>=i;++i)ans=ans*(m+i)/i; return ans;}const int MOD=3389;LL ksm(LL a,LL b){ LL ans=1; for(;b;b>>=1,a=a*a%MOD)if(b&1)ans=ans*a%MOD; return ans;}const int N=200;int vis[N];int Prime[N];int cnt=0;void Pre(){ for(int i=2;i
sum)break; } }}int n;int Quick_Pow(int x,int k){ cout<
<<" "<
<<'\n'; int ret=1; while(k){ if(k%2){ ret=ret*x; } k/=2; x=x*x; } cout<
<<'\n'; return ret;}int main(){// freopen("test.in","r",stdin); Pre(); cin>>n; int tot=0; for(int i=1;i<=n;++i){ cin>>D[i]; tot+=D[i]; if(!D[i]&&n>1){ cout<<0; return 0; } } if(tot!=2*n-2){ cout<<0; return 0; } if(n<=1){ cout<<1; return 0; } Solve(A,n-2); for(int i=1;i<=n;++i){ memset(B,0,sizeof(B)); Solve(B,D[i]-1); for(int j=1;j<=cnt;++j){ A[j]-=B[j]; } } ans=1; for(int i=1;i<=cnt;++i){// cout<
<<" "<
<<'\n'; if(A[i]){ for(int j=1;j<=A[i];++j) ans=ans*Prime[i]; } } cout<

 

转载于:https://www.cnblogs.com/Leo-JAM/p/10079097.html

你可能感兴趣的文章
mbed学习之 PWMOUT
查看>>
【旧文章搬运】隐藏驱动完整攻略(基础篇)
查看>>
maven快速入门
查看>>
NSFileHandle(文件对接器)
查看>>
初试部署自己的网站到服务器
查看>>
随机获取10条数据的方法
查看>>
Linux下搭建Python开发环境部署
查看>>
[Ramda] Filter, Reject and Partition
查看>>
servlet中不能没有无参构造函数
查看>>
js 中{},[]中括号,大括号使用详解
查看>>
JavaScript变量及数据类型
查看>>
Python 笔试 —— 效率与优雅
查看>>
windows 10 使用 tricks
查看>>
音乐的聆听 & 古典音乐的入门
查看>>
eclipse打开html文件
查看>>
转csdn某位同学的 感谢bmfont
查看>>
linux 添加、删除 route
查看>>
oracle 常用的几个网址
查看>>
oracle 12.2.0.1 使用 active dataguard broker 之一
查看>>
robotframework连接mysql数据库
查看>>