# [ZJOI 2012]数列

## Description

A_n=\left{\begin{aligned}&0,&n=0\&1,&n=1\&A_\frac{n}{2},&2\mid n\&A_{\left\lfloor\frac{n}{2}\right\rfloor}+A_{\left\lceil\frac{n}{2}\right\rceil},&\text{otherwise}\end{aligned}\right.

$t$ 组询问，每次询问 $A_n$ 为多少。

$1\leq t\leq 20, 1\leq n\leq 10^{100}$

## Code

#include <bits/stdc++.h>
using namespace std;
const int N = 100+5;

struct BIGN {
int a[N], l;
BIGN () {memset(a, l = 0, sizeof(a)); }
BIGN (int x) {memset(a, 0, sizeof(a)); l = 1, a[1] = x; }
bool operator == (const BIGN &b) const {
if (l != b.l) return false;
for (int i = l; i >= 1; i--)
if (a[i] != b.a[i]) return false;
return true;
}
bool operator < (const BIGN &b) const {
if (l != b.l) return l < b.l;
for (int i = l; i >= 1; i--)
if (a[i] != b.a[i]) return a[i] < b.a[i];
return false;
}
BIGN operator + (BIGN b) {
BIGN ans; ans.l = max(l, b.l);
if (l <= b.l) for (int i = l+1; i <= b.l; i++) a[i] = 0;
if (b.l <= l) for (int i = b.l+1; i <= l; i++) b.a[i] = 0;
for (int i = 1; i <= ans.l; i++)
ans.a[i] = (a[i]+b.a[i]);
ans.a[ans.l+1] = 0;
for (int i = 1; i <= ans.l; i++)
ans.a[i+1] += ans.a[i]/10, ans.a[i] %= 10;
if (ans.a[ans.l+1]) ++ans.l;
return ans;
}
void get() {
char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') a[++l] = ch-'0', ch = getchar();
reverse(a+1, a+l+1);
}
void put() {
for (int i = l; i >= 1; i--) putchar(a[i]+'0');
puts("");
}
BIGN div() {
BIGN ans; ans.l = l; int m = 0;
for (int i = l; i >= 1; i--)
ans.a[i] = (m*10+a[i])/2, m = (m*10+a[i])%2;
if (!ans.a[l]) --ans.l;
return ans;
}
} n, m;
int t;
map<BIGN, BIGN> mp;

BIGN dfs(BIGN n) {
if (mp.count(n)) return mp[n];
if (n == BIGN()) return BIGN();
if (n == BIGN(1)) return BIGN(1);
BIGN t = n.div();
if (n.a[1]&1) return mp[n] = dfs(t)+dfs(t+BIGN(1));
else return mp[n] = dfs(t);
return mp[n];
}
int main() {
scanf("%d\n", &t);
while (t--) {
n = BIGN(); n.get();
dfs(n).put();
}
return 0;
}
posted @ 2020-03-06 11:37  NaVi_Awson  阅读(190)  评论(0编辑  收藏  举报