首页 > 其他分享 >CF932D Tree

CF932D Tree

时间:2023-06-23 14:00:35浏览次数:46  
标签:cnt last int ll Tree -- 倍增 CF932D

题目链接

题目

见链接。

题解

知识点:倍增。

注意到,题目其实要求我们,每次要选最近一个权值大于等于自己的祖先,可以看出固定点生成出来的序列是固定的。因此,考虑设 \(f_{i,j}\) 为从 \(j\) 出发按规则向上走 \(2^i\) 次的点,设 \(b_{i,j}\) 为从 \(j\) 出发按规则向上走 \(2^i\) 次的所有序列点的权值和。

对于查询,需要注意要手动避免越界的 \(0\) 号节点问题,其余和正常倍增一致。

对于修改,由于是尾部追加,因此倍增可以支持,需要先确定向上第一个点是谁:

  1. 若新加点比它父亲小,那么直接设为它父亲。
  2. 否则,从父亲出发生成的序列中,找到比自己大的第一个点,显然可以用倍增找到。

随后更新一下倍增数组即可。

时间复杂度 \(O(Q \log Q)\)

空间复杂度 \(O(Q \log Q)\)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 400007;
int cnt;
int a[N];

int f[27][N];
ll b[27][N];
void update(int u, ll w) {
    a[++cnt] = w;
    if (a[u] >= a[cnt]) {
        f[0][cnt] = u;
        b[0][cnt] = a[u];
    }
    else {
        for (int i = 20;i >= 0;i--) {
            if (!f[i][u]) continue;
            if (a[f[i][u]] < a[cnt]) u = f[i][u];
        }
        f[0][cnt] = f[0][u];
        b[0][cnt] = a[f[0][u]];
    }
    for (int i = 1;i <= 20;i++) {
        f[i][cnt] = f[i - 1][f[i - 1][cnt]];
        b[i][cnt] = b[i - 1][cnt] + b[i - 1][f[i - 1][cnt]];
    }
}

int get_ans(int u, ll k) {
    if (a[u] > k) return 0;
    int ans = 1;
    ll sum = a[u];
    for (int i = 20;i >= 0;i--) {
        if (!f[i][u]) continue;
        if (sum + b[i][u] <= k) {
            sum += b[i][u];
            ans += 1 << i;
            u = f[i][u];
        }
    }
    return ans;
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    ++cnt;
    int Q;
    cin >> Q;
    ll last = 0;
    while (Q--) {
        int op;
        ll p, q;
        cin >> op >> p >> q;
        if (op == 1) {
            int r = p ^ last;
            ll w = q ^ last;
            update(r, w);
        }
        else {
            int r = p ^ last;
            ll x = q ^ last;
            cout << (last = get_ans(r, x)) << '\n';
        }
    }
    return 0;
}

标签:cnt,last,int,ll,Tree,--,倍增,CF932D
From: https://www.cnblogs.com/BlankYang/p/17499071.html

相关文章

  • NC200179 Colorful Tree
    题目链接题目题目描述Atreestructurewithsomecolorsassociatedwithitsverticesandasequenceofcommandsonitaregiven.Acommandiseitheranupdateoperationoraqueryonthetree.Eachoftheupdateoperationschangesthecolorofaspecifiedvert......
  • TreeSaver.js 的工作流程逻辑
    Treesaver是浏览器大小尺寸敏感(size-sensitive)的,会就着当前的浏览器尺寸(browsersize),选用不同的分栏表格(grid)做排版。初始化TreeSaver.js框架的入口源代码在后面可以看到:https://github.com/Treesaver/treesaver/blob/master/src/init.js这里的代码用到了Google开发的JS库:Closur......
  • Win7环境下TreeSaver编译环境的搭配
    首先你需要先搭配出”Win7环境下TreeSaver例子环境的搭配”然后才能继续下一步编译环境。例子环境搭配后,你可以在源代码目录下执行paver命令,搭配例子测试环境,也可以执行paverdebug生成带调试注释信息的treesaver脚本,当然也可以使用paverclean删除生成的文件。这些可以......
  • sourcetree忽略文件
    SourceTree默认使用的是全局缓存配置,这个配置文件在SourceTree–>Preferences–>Git–>GlobalIgnoreList可以看到。如下图:如果想针对某个项目单独做,则请参考下面文章:http://www.ifeegoo.com/git-code-management-dot-gitignore-file-has-no-effect-solution.html 这时......
  • CF383C Propagating tree
    题目链接题目见链接。题解知识点:DFS序,树状数组。我们需要对子树的不同奇偶层加减,用dfn序可以解决子树问题,但是并不能直接分奇偶。一种比较麻烦的思路是,将dfn序分成两个序列,一个是偶数层点序,一个是奇数层点序列,处理两个序列对于某个点作为子树根节点时,开始和结束节点,然后就可......
  • 【vue3】实现el-tree组件
     禾小毅csdn博客【vue3】实现el-tree组件,将不同层级的箭头修改成自定义图标的组件封装及调用【vue3】实现简易的“百度网盘”文件夹的组件封装实现【vue3】实现公共搜索组件,在当前页搜索的路由跳转不能改变当前值的操作,使用bus/event-emitter派发器......
  • linux gpio dev,linux gpio子系统 devicetree中GPIO_ACTIVE_LOW
    一直没怎么理解GPIO_ACTIVE_LOW的作用对于以上的dts你应该再熟悉不过,当然这里不是教你如何使用dts,而是关注gpio和irq最后一个数字可以如何利用。例如rst-gpio的OF_GPIO_ACTIVE_LOW代表什么意思呢?可以理解为低有效。什么意思呢?举个例子,正常情况下,我们需要一个gpio口控制灯,我们认......
  • Vue3 element-Plus el-tree 权限树 传值给后端及回显问题
    内容:权限在新增人员时候选择传给后端并且编辑回显坑:1.传给后端的权限数组需要传父级id例如:一级目录下有二级目录和2-2目录,选了2-2目录,需要把一级目录的id也给后端2.回显的时候后端会把权限数组id都给你(包括一级目录),如果直接回显的话会默认一级下所有目录都选中 代......
  • TreeMap
    TreeMap的使用publicstaticvoidmain(String[]args){ TreeMap<String,Integer>map=newTreeMap<>(); //添加元素 Integerput1=map.put("大文",25); Integerput2=map.put("小文",26); Integerput3=map.put("小王",......
  • 哈夫曼树(Huffman Tree)的基本概念介绍
    哈夫曼树(HuffmanTree)是一种常用的数据结构,用于实现数据压缩和编码。它是由美国计算机科学家DavidA.Huffman于1952年提出的,被广泛应用于通信、压缩算法和信息存储等领域。哈夫曼树主要用于根据字符出现的频率构建最优的前缀编码,以便在压缩数据时能够有效地减少所需的比特数。该......