您的位置:首页 > 其它

【BZOJ1089】[SCOI2003]严格n元树【递推】【高精度】

2016-03-04 20:56 555 查看
以为可以组合数分类递推求和,然而还是too naive。

设f[i]为高度小于等于i的树的方案数,那么有f[i] = (f[i - 1] ^ n) + 1。

答案为f[d] - f[d - 1]

然后敲个高精度就好啦。

话说最大数据似乎根本跑不了。

/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 10005;

struct bigint {
int num[maxn], len;

bigint() {
for(int i = 0; i < maxn; i++) num[i] = 0;
len = 1;
}

void read(int x) {
for(len = 0; x; x /= 10) num[len++] = x % 10;
}

bigint operator + (const bigint &a) {
bigint c; c.len = max(len, a.len) + 1;
for(int i = 0; i < c.len; i++) {
c.num[i] += num[i] + a.num[i];
c.num[i + 1] += c.num[i] / 10;
c.num[i] %= 10;
}
for(; c.len > 1 && !c.num[c.len - 1]; c.len--);
return c;
}

bigint operator - (const bigint &a) {
bigint c; c.len = max(len, a.len);
for(int i = 0; i < c.len; i++) {
c.num[i] += num[i] - a.num[i];
if(c.num[i] < 0) {
c.num[i] += 10;
c.num[i + 1] -= 1;
}
}
for(; c.len > 1 && !c.num[c.len - 1]; c.len--);
return c;
}

bigint operator * (const bigint &a) {
bigint c; c.len = len + a.len + 1;
for(int i = 0; i < len; i++) for(int j = 0; j < a.len; j++)
c.num[i + j] += num[i] * a.num[j];
for(int i = 0; i < c.len; i++) {
c.num[i + 1] += c.num[i] / 10;
c.num[i] %= 10;
}
for(; c.len > 1 && !c.num[c.len - 1]; c.len--);
return c;
}

bigint operator ^ (int n) {
bigint ans; ans.read(1);
for(bigint t = *this; n; n >>= 1, t = t * t) if(n & 1) ans = ans * t;
for(; ans.len > 1 && !ans.num[ans.len - 1]; ans.len--);
return ans;
}

void print() {
for(int i = len - 1; i >= 0; i--) printf("%d", num[i]);
}

} f2, f1, E;

int main() {
int n, d; scanf("%d%d", &n, &d);

E.read(1); f1 = E;
for(int i = 1; i <= d; i++)
if(i & 1) f2 = (f1 ^ n) + E;
else f1 = (f2 ^ n) + E;
if(~d & 1) swap(f1, f2);
f2 = f2 - f1;

f2.print();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  公式 高精度