zoukankan      html  css  js  c++  java
  • [bzoj1089] 严格n元树

    Description

    如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树。如果该树中最底层的节点深度为d(根的深度为0),那么我们称它为一棵深度为d的严格n元树。例如,深度为2的严格2元树有三个,如下图:

    给出n, d,编程数出深度为d的n元树数目。

    Input

    仅包含两个整数n, d( 0 < n < = 32, 0 < = d < = 16)

    Output

    仅包含一个数,即深度为d的n元树的数目。

    Sample Input1

    2 2
    

    Sample Output1

    3
    

    Sample Input2

    2 3
    

    Sample Output2

    21
    

    Sample Input3

    3 5
    

    Sample Output3

    58871587162270592645034001
    

    题解

    (f(i))表示深度小于等于(i)的严格(n)元树的总个数,则深度为(i)的严格(n)元树(f(i)-f(i-1))

    分析状态转移方程,再将深度为(i-1)的树的根节点分别做一棵深度为(1)的严格(n)元树的叶子节点,再加上一个也不加的,这个总数不正是(f(i))吗?

    所以状态转移方程为(f(i)=f(i-1)^n+1),由于答案是很大的,所以要有高精度,具体见代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<vector>
    #include<iomanip>
    #include<bitset>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #define rad 1000
    using namespace std;
    
    const int D=30,L=5000;
    int n,d;
    struct data
    {
    	int v[L],l;
    }f[D];
    
    data operator*(data a,data b)
    {
    	data c;
    	c.l=a.l+b.l;
    	for(int i=1;i<=c.l;++i) c.v[i]=0;
    	for(int i=a.l;i;--i)
    		for(int j=b.l;j;--j)
    			c.v[i+j-1]+=a.v[i]*b.v[j];
    	for(int i=1;i<=c.l;++i)
    		if(c.v[i]>=rad)
    		{
    			if(i==c.l) ++c.l;
    			c.v[i+1]+=c.v[i]/rad,
    			c.v[i]%=rad;
    		}
    	while((c.l>1)&&(!c.v[c.l])) --c.l;
    	return c;
    }
    
    data operator^(data a,int b)
    {
    	data c;
    	c.v[1]=1,c.l=1;
    	for(int i=b;i;i>>=1,a=a*a)
    		if(i&1) c=c*a;
    	return c;
    }
    
    data operator+(data a,int b)
    {
    	a.v[1]+=b;
    	for(int i=1;a.v[i]>=rad;++i)
    	{
    		a.v[i+1]+=a.v[i]/rad,
    		a.v[i]%=rad,
    		a.l=max(a.l,i+1);
    	}
    	return a;
    }
    
    data operator-(data a,data b)
    {
    	for(int i=1;i<=a.l;++i)
    	{
    		a.v[i]-=b.v[i];
    		if(a.v[i]<0)
    		{
    			a.v[i]+=rad,
    			--a.v[i+1];
    		}
    	}
    	while((a.l>1)&&(!a.v[a.l])) --a.l;
    	return a;
    }
    
    void Print(data a)
    {
    	printf("%d",a.v[a.l]);
    	for(int i=a.l-1;i;--i) printf("%03d",a.v[i]);
    	putchar('
    ');
    }
    
    int main()
    {
    	scanf("%d%d",&n,&d);
    	if(d==0) {puts("1");return 0;}
    	f[0].l=1,f[0].v[1]=1;
    	for(int i=1;i<=d;++i)
    		f[i]=(f[i-1]^n)+1;
    	Print(f[d]-f[d-1]);
    	return 0;
    }
    

    推荐博文「BZOJ1089」[SCOI2003] 严格n元树

  • 相关阅读:
    应用Druid监控SQL语句的执行情况
    J2EE应用监控后台执行SQL
    maven环境搭建
    【机器学习】Sklearn库主成分分析PCA降维的运用实战
    PCA降维算法
    80行Python实现-HOG梯度特征提取(转载)
    HOG特征提取算法原理(转载)
    数据预处理方法 总结
    【AI换脸】Faceswap源代码换脸软件安装指南(转)
    人工智能领域的会议和期刊(转载)
  • 原文地址:https://www.cnblogs.com/hihocoder/p/12111711.html
Copyright © 2011-2022 走看看