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

[ZJOI 2012]数列

时间:2020-03-06 12:44:45      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:script   putchar   rev   log   ++   多少   opera   math   ret   

Description

题库链接

给你一个数列 \(A\),满足递推公式
\[ 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{else}\end{aligned}\right. \]

\(t\) 组询问,每次询问 \(A_n\) 为多少。

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

Solution

容易发现计算 \(A_n\) 时,如果我们不断根据递推公式去运算,最后只会有 \(O(\log n)\) 种不同状态,因此我们可以直接暴力递归,然后用 map 存下已出现过的状态记忆化搜索就好了。

这题高精度不打错问题就不大。

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;
}

[ZJOI 2012]数列

标签:script   putchar   rev   log   ++   多少   opera   math   ret   

原文地址:https://www.cnblogs.com/NaVi-Awson/p/12425631.html

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