• 【Codeforces】894D. Ralph And His Tour in Binary Country 思维+二分


    题意

    给定一棵$n$个节点完全二叉树,$m$次询问,每次询问从$a$节点到其它所有节点(包括自身)的距离$L$与给定$H_a$之差$H_a-L$大于$0$的值之和


    对整棵树从叶子节点到父节点从上往下预处理出每个节点到它的子节点的距离$d$并排序,因为每个节点最多有$log n$个父亲,所以预处理时间复杂度为$O(nlog n)$

    通过二分查找可以得到任意节点到子节点的满足条件的距离,对于每个询问,查询当前节点的子树权值和,并不断向树根转移,每次计算兄弟节点对应的权值和(相当于看作以当前节点为根重构树),直到转移到树根

    时间复杂度$O((n+m)log^2n)$

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    int n, m, L[1000005], a, h, tmp, lch, rch, last;
    long long ans = 0;
    vector<int> d[1000005];
    vector<LL> pre[1000005];
    LL query(int x, int h) {
        if(h <= 0) return 0;
        int p = upper_bound(d[x].begin(), d[x].end(), h) - d[x].begin();
        return 1LL * p * h - 1LL * pre[x][p - 1];
    }
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 2; i <= n; ++i) scanf("%d", &L[i]);
        for(int i = n; i >= 1; --i) {
            d[i].push_back(0);
            lch = i << 1; rch = i << 1 | 1;
            if(lch <= n) {
                for(int j = 0; j < d[lch].size(); ++j) d[i].push_back(d[lch][j] + L[lch]);
            }
            if(rch <= n) {
                for(int j = 0; j < d[rch].size(); ++j) d[i].push_back(d[rch][j] + L[rch]);
            }
            sort(d[i].begin(), d[i].end());
            pre[i].resize(d[i].size());
            for(int j = 1; j < pre[i].size(); ++j) {
                pre[i][j] = pre[i][j - 1] + d[i][j];
            }
        }
        for(; m; --m) {
            scanf("%d%d", &a, &h); ans = 0;
            tmp = a; last = 0;
            while(tmp) {
                if(h < 0) break; ans += h;
                lch = tmp << 1; rch = tmp << 1 | 1;
                if(lch <= n && lch != last) {
                    ans += query(lch, h - L[lch]);
                }
                if(rch <= n && rch != last) {
                    ans += query(rch, h - L[rch]);
                }
                h -= L[tmp]; last = tmp; tmp >>= 1;
            }
            printf("%I64d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    递归
    书评:《C程序设计语言》
    下一代互联网,今日揭开面纱:IPv6真的要来了
    庆祝Alan Mathison Turing(艾伦·图灵)诞辰100周年!
    svn常用命令行和批处理
    ORACLE 9i数据导入到ORACLE 10G中文出现的乱码问题
    Oracle 11G 的客户端,不再支持连接到ORACLE 8I
    DB2 一个汉字的Byte数,太操蛋了
    关于Windows 7 64位下Visual Studio 2010 开发的Asp.net程序连接Oracle 的出现的问题
    Web Frame 跨域调用Session 丢失问题
  • 原文地址:https://www.cnblogs.com/ogiso-setsuna/p/7911772.html
Copyright © 2020-2023  润新知