如有错误,请留言提醒,不要坑到小朋友
Description
如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树。如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树。例如:深度为2的严格2元树有三个,如下图:
给出n,d,编程序数出深度为d的n元树数目。
Input
仅包含两个整数n,d(0 < n < = 32,0 <= d <= 16)。输入数据保证你不需要考虑某一层多于1024个节点的树(nd<=1024)。提示:答案保证不超过200位十进制数。
Output
仅包含一个数,既深度为d的n元树的数目。
Sample Input
【样例输入1】 2 2 【样例输入2】 2 4
Sample Output
【样例输出1】 3 【样例输出2】 651
f[i]代表深度为i的情况下n元树的数目
tot[i]代表深度小于等于i的情况下n元树的数目f[i]=tot[i-1]^n-tot[i-2]^n
为什么要减呢
因为tot[i-1]^n包括了最深度小于i-1的情况;#include<cstdlib> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<climits> #include<cctype> #include<string> #define maxn 33 using namespace std; namespace ljq{ struct bign{ #define max(a,b) ((a)>(b)?(a):(b)) static const int maxlen=5000,limit=10000,width=4; int len,bit[maxlen]; void clearbit(){memset(bit,0,sizeof(bit));} void delete0(){for(;!bit[len-1]&&len>1;--len);} int& operator[](int p){return bit[p];} bign(int p=0){*this=p;} bign& operator=(int p){ clearbit(); len=p?0:1; for(;p;p/=limit)bit[len++]=p%limit; return *this; } bign(const char*p){*this=p;} bign& operator=(const char*p){ clearbit(); for(int i=strlen(p)-1;i>=0;i-=4){ int now=0; for(int j=max(0,i-width+1);j<=i;j++)now=now*10+p[j]-'0'; bit[len++]=now; } return *this; } bign& operator+=(bign b){ len=max(len,b.len)+1; for(int i=0;i<len;i++)bit[i]+=b[i],bit[i+1]+=bit[i]/limit,bit[i]%=limit; delete0(); return *this; } bign& operator-=(bign b){ for(int i=0;i<len;i++){bit[i]-=b[i];if(bit[i]<0)bit[i]+=limit,bit[i+1]--;} delete0(); return *this; } bign& operator*=(bign b){ bign a=*this; len=a.len+b.len; clearbit(); for(int i=0;i<a.len;i++) for(int j=0;j<b.len;j++) bit[i+j]+=a.bit[i]*b.bit[j],bit[i+j+1]+=bit[i+j]/limit,bit[i+j]%=limit; delete0();return *this; } bign& operator/=(int b){ for(int i=len-1;i>0;--i)bit[i-1]+=limit*(bit[i]%b),bit[i]/=b;bit[0]/=b; delete0();return *this; } bool operator<(bign b)const{ if(len>b.len)return 0; if(len<b.len)return 1; for(int i=len-1;i>=0;i--) if(bit[i]!=b[i])return bit[i]<b[i]; return bit[0]<b[0]; } bool operator==(bign b)const{return !(*this<b)&&!(b<*this);} bool operator!=(bign b)const{return !(*this==b);} bool operator>(bign b)const{return b<*this;} bool operator<=(bign b)const{return !(*this>b);} bool operator>=(bign b)const{return !(*this<b);} }; bign operator+(bign a,bign b){return a+=b;} bign operator-(bign a,bign b){return a-=b;} bign operator*(bign a,bign b){return a*=b;} bign operator/(bign a,int b){return a/=b;} istream& operator>>(istream &is,bign &p){ string s; is>>s;p=s.c_str(); return is; } ostream& operator<<(ostream &os,bign &p){ os.fill('0');os<<p.bit[p.len-1]; for(int i=p.len-2;i>=0;i--){os.width(bign::width);os<<p.bit[i];} return os; } bign sqrt(bign x){ bign l=1,r=x; while(l<=r){ bign mid=(l+r)/2; if(x<mid*mid)r=mid-1;else l=mid+1; } return r; } }using ljq::bign; bign f[maxn],tot[maxn]; int n,m; bign ksm(bign a,int b){ bign t,y; t=1;y=a; while(b){ if(b&1)t=t*y; y=y*y; b=b>>1; } return t; } void init(){ tot[0]=f[0]=1; f[1]=1; tot[1]=2; for(int j=2;j<=m;j++){ f[j]=ksm(tot[j-1],n)-ksm(tot[j-2],n); tot[j]=tot[j-1]+f[j]; } } int main(){ scanf("%d%d",&n,&m); init(); cout<<f[m]<<endl; }
[Spoj]严格n元树(dp)
最新推荐文章于 2021-03-05 21:35:52 发布