zoukankan      html  css  js  c++  java
  • BZOJ1089:[SCOI2003]严格n元树(DP,高精度)

    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

    Solution

    DP方程好想= =
    $f[i]$表示深度不超过$i$的树的种数
    $f[i]=f[i-1]^n+1$。加1是因为儿子可能为空。
    最后答案为$f[d]-f[d-1]$
    需要高精度……不过懒得写了直接套了个板子QAQ

    Code

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #define N (509)
      5 using namespace std;
      6 
      7 struct bign
      8 {
      9     int len, s[N];
     10     bign ()
     11     {
     12         memset(s, 0, sizeof(s));
     13         len = 1;
     14     }
     15     bign (int num) { *this = num; }
     16     bign (const char *num) { *this = num; }
     17     bign operator = (const int num)
     18     {
     19         char s[N];
     20         sprintf(s, "%d", num);
     21         *this = s;
     22         return *this;
     23     }
     24     bign operator = (const char *num)
     25     {
     26         for(int i = 0; num[i] == '0'; num++) ;  //去前导0
     27         len = strlen(num);
     28         for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';
     29         return *this;
     30     }
     31     bign operator + (const bign &b) const //+
     32     {
     33         bign c;
     34         c.len = 0;
     35         for(int i = 0, g = 0; g || i < max(len, b.len); i++)
     36         {
     37             int x = g;
     38             if(i < len) x += s[i];
     39             if(i < b.len) x += b.s[i];
     40             c.s[c.len++] = x % 10;
     41             g = x / 10;
     42         }
     43         return c;
     44     }
     45     bign operator += (const bign &b)
     46     {
     47         *this = *this + b;
     48         return *this;
     49     }
     50     void clean()
     51     {
     52         while(len > 1 && !s[len-1]) len--;
     53     }
     54     bign operator * (const bign &b) //*
     55     {
     56         bign c;
     57         c.len = len + b.len;
     58         for(int i = 0; i < len; i++)
     59         {
     60             for(int j = 0; j < b.len; j++)
     61             {
     62                 c.s[i+j] += s[i] * b.s[j];
     63             }
     64         }
     65         for(int i = 0; i < c.len; i++)
     66         {
     67             c.s[i+1] += c.s[i]/10;
     68             c.s[i] %= 10;
     69         }
     70         c.clean();
     71         return c;
     72     }
     73     bign operator *= (const bign &b)
     74     {
     75         *this = *this * b;
     76         return *this;
     77     }
     78     bign operator - (const bign &b)
     79     {
     80         bign c;
     81         c.len = 0;
     82         for(int i = 0, g = 0; i < len; i++)
     83         {
     84             int x = s[i] - g;
     85             if(i < b.len) x -= b.s[i];
     86             if(x >= 0) g = 0;
     87             else
     88             {
     89                 g = 1;
     90                 x += 10;
     91             }
     92             c.s[c.len++] = x;
     93         }
     94         c.clean();
     95         return c;
     96     }
     97     bign operator -= (const bign &b)
     98     {
     99         *this = *this - b;
    100         return *this;
    101     }
    102     bign operator / (const bign &b)
    103     {
    104         bign c, f = 0;
    105         for(int i = len-1; i >= 0; i--)
    106         {
    107             f = f*10;
    108             f.s[0] = s[i];
    109             while(f >= b)
    110             {
    111                 f -= b;
    112                 c.s[i]++;
    113             }
    114         }
    115         c.len = len;
    116         c.clean();
    117         return c;
    118     }
    119     bign operator /= (const bign &b)
    120     {
    121         *this  = *this / b;
    122         return *this;
    123     }
    124     bign operator % (const bign &b)
    125     {
    126         bign r = *this / b;
    127         r = *this - r*b;
    128         return r;
    129     }
    130     bign operator %= (const bign &b)
    131     {
    132         *this = *this % b;
    133         return *this;
    134     }
    135     bool operator < (const bign &b)
    136     {
    137         if(len != b.len) return len < b.len;
    138         for(int i = len-1; i >= 0; i--)
    139         {
    140             if(s[i] != b.s[i]) return s[i] < b.s[i];
    141         }
    142         return false;
    143     }
    144     bool operator > (const bign &b)
    145     {
    146         if(len != b.len) return len > b.len;
    147         for(int i = len-1; i >= 0; i--)
    148         {
    149             if(s[i] != b.s[i]) return s[i] > b.s[i];
    150         }
    151         return false;
    152     }
    153     bool operator == (const bign &b)
    154     {
    155         return !(*this > b) && !(*this < b);
    156     }
    157     bool operator != (const bign &b)
    158     {
    159         return !(*this == b);
    160     }
    161     bool operator <= (const bign &b)
    162     {
    163         return *this < b || *this == b;
    164     }
    165     bool operator >= (const bign &b)
    166     {
    167         return *this > b || *this == b;
    168     }
    169     string str() const
    170     {
    171         string res = "";
    172         for(int i = 0; i < len; i++) res = char(s[i]+'0') + res;
    173         return res;
    174     }
    175 };
    176 
    177 istream& operator >> (istream &in, bign &x)
    178 {
    179     string s;
    180     in >> s;
    181     x = s.c_str();
    182     return in;
    183 }
    184 
    185 ostream& operator << (ostream &out, const bign &x)
    186 {
    187     out << x.str();
    188     return out;
    189 }
    190 
    191 bign Pow(bign a,int b)
    192 {
    193     bign ans=1;
    194     for (int i=1; i<=b; ++i)
    195         ans=ans*a;
    196     return ans;
    197 }
    198 
    199 bign f[33],ans;
    200 int n,d;
    201 
    202 int main()
    203 {
    204     scanf("%d%d",&n,&d);
    205     if (!d){puts("1"); return 0;}
    206     f[0]=1;
    207     for (int i=1; i<=d; ++i)
    208         f[i]=Pow(f[i-1],n)+1;
    209     cout<<f[d]-f[d-1];
    210 }
  • 相关阅读:
    一键保存网页为PDF
    Redis使用总结之与Memcached异同
    wxWidgets的安装编译、相关配置、问题分析处理
    python抓取网页图片
    bootstrap插件学习-bootstrap.popover.js
    CC.NET模板简化配置
    密码技术应用系列之开篇
    【Cocos2d-X开发学习笔记】第05期:渲染框架之布景层类(CCLayer)的使用
    ImageMagick还是GraphicsMagick?
    RESTClient 控件 从服务器获得数据集 REST
  • 原文地址:https://www.cnblogs.com/refun/p/9806766.html
Copyright © 2011-2022 走看看