zoukankan      html  css  js  c++  java
  • [ZJOI 2012]数列

    Description

    题库链接

    给你一个数列 (A),满足递推公式
    [ A_n=left{egin{aligned}&0,&n=0\&1,&n=1\&A_frac{n}{2},&2mid n\&A_{leftlfloorfrac{n}{2} ight floor}+A_{leftlceilfrac{n}{2} ight ceil},& ext{otherwise}end{aligned} ight. ]

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

    (1leq tleq 20, 1leq nleq 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
    ", &t);
        while (t--) {
            n = BIGN(); n.get();
            dfs(n).put();
        }
        return 0;
    }
  • 相关阅读:
    5分钟带你了解Kafka的技术架构
    聊聊我的知识体系
    你分得清楚Maven的聚合和继承吗?
    为抖音而生的多闪,如何获取抖音的用户数据?
    消息中间件系列第3讲:使用消息队列需要考虑的几个问题
    消息中间件系列第2讲:如何进行消息队列选型?
    消息中间件系列第1讲:为什么要用消息队列?
    JVM规范系列开篇:为什么要读JVM规范?
    安全编码实践之三:身份验证和会话管理防御
    安全编码实践之二:跨站脚本攻击防御
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/12425631.html
Copyright © 2011-2022 走看看