• bzoj1089 [SCOI2003]严格n元树(dp+高精)


    1089: [SCOI2003]严格n元树

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 1899  Solved: 954
    [Submit][Status][Discuss]

    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 Input

    【样例输入1】
    2 2

    【样例输入2】
    2 3

    【样例输入3】
    3 5

    Sample Output

    【样例输出1】
    3

    【样例输出2】
    21

    【样例输出2】
    58871587162270592645034001
    /*
    定义S[i]代表深度<=i的严格n元树的个数
    那么最后S[d]-S[d-1]就是答案
    那么对于S[i],我们由S[i-1]递推来,
    我们考虑新加一个根节点,然后根节点有n个子节点,每个子节点都可以建一颗深度<=i-1的树,那么每个
    子节点都有S[i-1]种选法,那么n个子节点就有S[i-1]^n选法,再加上都不选,就是深度为0的情况
    那么S[i]:=(S[i-1]^n)+1;
    */
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<iomanip>
    using namespace std;
    struct long_int{
        int num[3000],cnt;
        void operator = (int y)
        {
            num[1]=y;cnt=1;
        }
        int& operator [] (int x)
        {
            return num[x];
        }
    }S[200];
    void operator *= (long_int &x,long_int &y)
    {
        long_int z=S[199];
        int i,j;
        for(i=1;i<=x.cnt;i++)
            for(j=1;j<=y.cnt;j++)
            {
                z[i+j-1]+=x[i]*y[j];
                z[i+j]+=z[i+j-1]/10000;
                z[i+j-1]%=10000;
            }
        z.cnt=x.cnt+y.cnt;
        if(!z[z.cnt])--z.cnt;
        x=z;
    }
    void operator ++ (long_int &x)
    {
        int i=1;x[1]++;
        while(x[i]==10000)x[i]=0,x[++i]++;
    }
    long_int operator - (long_int &x,long_int &y)
    {
        long_int z=S[199];
        int i;
        for(i=1;i<=x.cnt;i++)
        {
            z[i]+=x[i]-y[i];
            if(z[i]<0) z[i]+=10000,z[i+1]--;
            if(z[i]) z.cnt=i;
        }
        return z;
    }
    long_int operator ^ (long_int x,int y)
    {
        long_int z=S[199];z=1;
        while(y)
        {
            if(y&1) z*=x;
            x*=x;y>>=1;
        }
        return z;
    }
    ostream& operator << (ostream &os,long_int x)
    {
        int i;
        os<<x[x.cnt];
        for(i=x.cnt-1;i;i--)
            os<<setfill('0')<<setw(4)<<x[i];
            //os<<x[i];
        return os;
    }
    int n,d;
    int main()
    {
        int i;
        cin>>n>>d;
        if(!d)
        {
            puts("1");return 0;
        }
        S[0]=1;
        for(i=1;i<=d;i++)
            S[i]=S[i-1]^n,++S[i];
        cout<<S[d]-S[d-1]<<endl;
    }

     

     
     
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    链表习题(2)-一个集合用带头结点的单链表L表示,编写算法删除其值最大的结点。
    ubuntu14安装
    poi多sheet练习
    vmware虚拟机网络模式-仅主机模式
    vmware虚拟机网络模式-NAT模式
    vmware虚拟机网络模式-桥接模式
    IntelliJ IDEA 创建maven
    IntelliJ IDEA
    冒泡
    Java泛型 通配符? extends与super
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7528222.html
Copyright © 2020-2023  润新知