码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ1089——[SCOI2003]严格n元树

时间:2016-08-22 18:29:19      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:

1、题意:求深度为d的n叉树的个数。
2、分析:动态规划。。设Fi表示深度小于等于i的n叉树有多少,然后可以考虑dp,新加入一个点,设这个点为根,那么这个点的每个儿子都有Fi种方案,所以是Fni,加上这个点自己本身也是一个n叉树,所以Fi=Fni+1,这就是转移方程,别忘了高精度= =

#include <cstdio>
#include <cstdlib>
#include <cstring> 
#include <algorithm>
using namespace std;

inline int read(){
    char ch = getchar(); int x = 0, f = 1;
    while(ch < ‘0‘ || ch > ‘9‘){
        if(ch == ‘-‘) f = -1;
        ch = getchar(); 
    }
    while(‘0‘ <= ch && ch <= ‘9‘){
        x = x * 10 + ch - ‘0‘;
        ch = getchar();
    }
    return x * f;
}

struct bign{
    int a[210];
    int len;

    bign(){
        memset(a, 0, sizeof(a));
        len = 0;
    }

    inline bign get_bign(int rhs){
        bign ret;
        while(rhs){
            ret.a[++ ret.len] = rhs % 10;
            rhs /= 10;
        }
        return ret;
    }

    inline bool operator < (const bign& rhs) const{
        if(len < rhs.len) return 1;
        if(len > rhs.len) return 0;
        for(int i = len; i >= 1; i --){
            if(a[i] < rhs.a[i]) return 1;
            if(a[i] > rhs.a[i]) return 0;
        }
        return 0;
    }

    inline bool operator > (const bign& rhs) const{
        return rhs < *this;
    }

    inline bool operator == (const bign& rhs) const{
        return !((rhs < *this) | (*this < rhs));
    }

    inline bool operator <= (const bign& rhs) const{
        return *this == rhs || *this < rhs; 
    }

    inline bool operator >= (const bign& rhs) const{
        return *this == rhs || *this > rhs;
    }

    inline bool operator != (const bign& rhs) const{
        return !(*this == rhs);
    }

    inline bign operator * (bign& rhs) const{
        bign ret;
        for(int i = 1; i <= len; i ++){
            for(int j = 1; j <= rhs.len; j ++){
                ret.a[i + j - 1] += a[i] * rhs.a[j];
                ret.a[i + j] += ret.a[i + j - 1] / 10;
                ret.a[i + j - 1] %= 10; 
            }
        }
        ret.len = len + rhs.len - 1;
        if(ret.a[ret.len + 1]) ret.len ++;
    /*  puts("");
        for(int i = len; i >= 1; i --) printf("%d", a[i]);
        puts("");
        puts("*");
        rhs.print();
        puts("=");
        ret.print(); 
        puts("");*/
        return ret;
    }

    inline bign operator * (int& rhs){
        bign yt = get_bign(rhs);
        return *this * yt;
    } 

    inline bign operator + (bign& rhs) const{
        bign ret;
        ret.len = max(len, rhs.len);
        for(int i = 1; i <= ret.len; i ++){
            ret.a[i] += a[i] + rhs.a[i];
            ret.a[i + 1] += ret.a[i] / 10;
            ret.a[i] %= 10;
        }
        if(ret.a[ret.len + 1]) ret.len ++;
        return ret;
    }

    inline bign operator + (int& rhs){
        bign yt = get_bign(rhs);
        return *this + yt;
    }

    inline bign operator - (const bign& rhs) const{
        bign ret;
        for(int i = 1; i <= len; i ++){
            ret.a[i] += a[i] - rhs.a[i];
            if(ret.a[i] < 0) ret.a[i] += 10, ret.a[i + 1] --;
            if(ret.a[i]) ret.len = i;
        } 
        return ret;
    }

    inline bign operator - (int& rhs){
        bign yt = get_bign(rhs);
        return *this - yt;
    }  

    inline bign operator / (const int& rhs) const{
        bign ret;
        int x = 0;
        for(int i = len; i >= 1; i --){
            x = x * 10 + a[i];
            ret.a[i] = x / rhs;
            x %= rhs;
        }
        ret.len = len;
        while(!ret.a[ret.len] && ret.len) ret.len --;
        return ret;
    }

    inline int operator % (const int& rhs) const{
        int x = 0;
        for(int i = len; i >= 1; i --){
            x = x * 10 + a[i];
            x %= rhs;
        }
        return x;
    } 

    inline bign operator ^ (int rhs){
        bign ret; ret = get_bign(1);
        bign nbc = *this;
        //puts("fuck");
        //nbc.print(); 
        while(rhs){
            if(rhs & 1) ret = ret * nbc;
            nbc = nbc * nbc;
            rhs >>= 1;
        }
        //ret.print();
        return ret;
    }

    inline void operator = (int x){
        *this = get_bign(x);
        return;
    } 

    inline void print(){
        for(int i = len; i >= 1; i --) printf("%d", a[i]);
        //puts("");
    }
} F[20]; 

int main(){
    //freopen("0input.in", "r", stdin);
    int n = read(), d = read();
    if(d == 0){
        puts("1");
        return 0;
    }
    F[0] = 1;// F[0].print();
    for(int i = 1; i <= d; i ++){
        F[i] = F[i - 1] ^ n; //printf("^");F[i].print();
        F[i] = F[i] + F[0]; //F[i].print(); 
        //printf("N:%d\n", n);
    }
    (F[d] - F[d - 1]).print();
    return 0;
} 

BZOJ1089——[SCOI2003]严格n元树

标签:

原文地址:http://blog.csdn.net/qzh_1430586275/article/details/52278088

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!