• bzoj1089严格n元树——DP+高精度


    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1089

    f[d]为深度小于等于d的树的个数;

    从根节点出发,有n个子树,乘法原理可以得到 f[d] = f[d-1] ^ n + 1 ,加1是因为也可以没有根节点;

    需要高精度,直接重载运算符十分方便。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int const rad=1000;
    int n,d;
    struct data{
        int v[5005],l;
    }f[30];
    data operator*(data a,data b)
    {
        data c;
        for(int i=1;i<=a.l+b.l;i++)c.v[i]=0;
        for(int i=1;i<=a.l;i++)
            for(int j=1;j<=b.l;j++)
                c.v[i+j-1]+=a.v[i]*b.v[j];
        c.l=a.l+b.l;
        for(int i=1;i<=c.l;i++)
        {
            if(c.v[i]>=rad)
            {
                if(i==c.l)
                {
                    c.l++;
                    c.v[c.l]=c.v[i]/rad;
                }
                else c.v[i+1]+=c.v[i]/rad;
                c.v[i]%=rad;
            }
        }
        while(c.v[c.l]==0&&c.l>1)c.l--;
        return c;
    }
    data operator^(data a,int n)
    {
        data c;
        c.l=1;c.v[1]=1;
        while(n)
        {
            if(n&1)c=c*a;
            a=a*a;
            n>>=1;
        }
        return c;
    }
    data operator+(data a,int x)
    {
        a.v[1]+=x;
        int now=1;
        while(a.v[now]>=rad)a.v[now+1]+=a.v[now]/rad,a.v[now]%=rad,now++;
        a.l=max(a.l,now);
        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.v[a.l]==0&&a.l>1)a.l--;
        return a;
    }
    //void print(data a)
    //{
    //  for(int i=a.l;i;i--)
    //      printf("%d",a.v[i]);
    //}
    void print(data a)
    {
        printf("%d",a.v[a.l]);
        for(int i=a.l-1;i;i--)
            printf("%03d",a.v[i]);
        printf("
    ");
    }
    int main()
    {
        scanf("%d%d",&n,&d);
        if(d==0)
        {
            printf("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;
    }
    
  • 相关阅读:
    c#常用的技巧
    在Web应用程序中使用Castle ActiveRecord
    Castle Query返回System.String程序报错的解决方法
    C++标准转换运算符const_cast
    Linux目录解释
    [转载]存储过程与函数的区别
    详解GCC的下载和安装
    Linux控制台的快捷键
    Linux下软件的安装和卸载
    电路交换,报文交换和分组交换
  • 原文地址:https://www.cnblogs.com/Zinn/p/9134916.html
Copyright © 2020-2023  润新知