【文件夹合并——树链剖分,树状数组】

news/2025/2/22 13:48:59

题目

复杂度

O(n\cdot \log n \cdot \log n)

代码

#pragma GCC optimize(3)

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

const int N = 5e5 + 10;
const int M = 1e6 + 10;

int n, m;
vector<int> sub[N];                                           // 子文件夹
ll d[N];                                                      // 数据量
int h[N], e[M], ne[M], idx;                                   // 链式前向星
int dep[N], sz[N], son[N], dfn[N], fa[N], top[N], id[N], cnt; // 树链剖分
int tr[N];                                                    // 树状数组
void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void dfs1(int u)
{
    sz[u] = 1;
    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if (j == fa[u])
            continue; // fa[root] = 0;
        dep[j] = dep[u] + 1;
        fa[j] = u;
        dfs1(j);
        sz[u] += sz[j];
        if (sz[j] > sz[son[u]])
            son[u] = j;
    }
}

void dfs2(int u, int t)
{
    dfn[u] = ++cnt;
    id[cnt] = u;
    top[u] = t;

    if (!son[u])
        return;
    else
        dfs2(son[u], t);

    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        if (j == fa[u] || j == son[u])
            continue;
        dfs2(j, j);
    }
}

ll query(int x)
{
    ll retv = 0;

    for (; x; x -= x & -x)
        retv += tr[x];

    return retv;
}

ll query(int l, int r)
{
    return query(r) - query(l - 1);
}
void modify(int x, int v)
{
    for (; x <= n; x += x & -x)
        tr[x] += v;
}

ll nquery(int a, int b)
{
    ll retv = 0;

    while (top[a] != top[b])
    {
        if (dep[top[a]] < dep[top[b]])
            swap(a, b);
        retv += query(dfn[top[a]], dfn[a]);
        a = fa[top[a]];
    }

    if (dep[a] > dep[b])
        swap(a, b);
    retv += query(dfn[a], dfn[b]);
    
    return retv;
}

void nmodify(int x, int v)
{
    modify(dfn[x], v);
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    memset(h, -1, sizeof h);
    
    cin >> n >> m;
    for (int i = 2; i <= n; i++)
    {
        int f;
        cin >> f;
        sub[f].push_back(i);
        add(f, i);
        add(i, f);
    }
    for (int i = 1; i <= n; i++)
        cin >> d[i];

    dfs1(1);
    dfs2(1, 1);
    
    for(int i = 1; i <= n; i++)
        nmodify(i, 1);
        
    while (m--)
    {
        int op, x;
        cin >> op >> x;

        if (op == 1)
        {
            vector<int> t;
            for (int i : sub[x])
            {
                d[x] += d[i];
                nmodify(i, -1);
                for (int j : sub[i])
                    t.push_back(j);
            }

            sub[x] = t;
            cout << sub[x].size() << ' ' << d[x] << '\n';
        }
        else if (op == 2)
            cout << nquery(1, x) << '\n';
    }
}


http://www.niftyadmin.cn/n/5862345.html

相关文章

IO模型与NIO基础--NIO网络传输选择器--字符编码

放进NIO体系进行网络编程的工作流程&#xff1a; Selector的创建 通过调用Selector.open()方法创建一个Selector&#xff0c;如下&#xff1a; Selector selector Selector.open(); 向Selector注册通道 通过Channel.register()方法来实现&#xff0c; 注意&#xff1a;Chan…

Canvas进阶-4、边界检测(流光,鼠标拖尾)

1. 什么是边界检测&#xff1f; 在之前的开发中&#xff0c;物体在运动过程中一旦超出画布&#xff0c;就会消失&#xff0c;今天学习如何去检测是否碰到了边界&#xff0c;碰到边界后又会有哪些处理的办法。 边界检测&#xff0c;就是物体运动的限制范围。边界检测的范围&…

[实现Rpc] Dispatcher类的实现 | 开闭原则 | 测试 | 传gitee

目录 程序设计原则 说明 Dispatcher Callback 类 CallbackT 类 Dispatcher 类 测试 client server Debug ⭕参数传递错误 排查方法&#xff1a; 运行 记录&#xff1a; &#xff08;1&#xff09;Dispatcher类的功能&#xff1a; 注册消息的类型。回调函数映射关…

二叉树层序遍历的三种情况(总结)

这道题就是一个比较简单的层序遍历&#xff0c;只需要利用队列存放二叉树结点&#xff0c;队列的size代表每层的节点数也就是平均值的除数&#xff0c;利用一个结果数组记录每层平均值&#xff0c;最后返回。 需要注意的是&#xff0c;平均值定义成double类型。 代码如下&…

通信系统中物理层与网络层联系与区别

在通信系统中&#xff0c;物理层和网络层是OSI&#xff08;开放系统互连&#xff09;模型中的两个重要层次&#xff0c;分别位于协议栈的最底层和第三层。它们在功能、职责和实现方式上有显著的区别&#xff0c;但同时也在某些方面存在联系。以下是物理层与网络层的联系与区别的…

进程(2)

1.进程的消亡 &#xff08;1&#xff09;进程的退出 &#xff08;2&#xff09;进程资源的回收 僵尸进程&#xff1a;进程已经结束&#xff0c;但是未被其父进程回收。 如何避免僵尸进程&#xff1a; 2.函数 &#xff08;1&#xff09;void exit(int status) (2)pid_t wait…

记录:Docker 安装记录

今天在安装 ollama 时发现无法指定安装目录&#xff0c;而且它的命令行反馈内容很像 docker &#xff0c;而且它下载的模型也是放在 C 盘&#xff0c;那么如果我 C 盘空间不足&#xff0c;就装不了 deepseek-r1:70b &#xff0c;于是想起来之前安装 Docker 的时候也遇到过类似问…

AI汽车新风向:「死磕」AI底盘,引爆线控底盘新增长拐点

2025开年&#xff0c;DeepSeek火爆出圈&#xff0c;包括吉利、东风汽车、上汽、广汽、长城、长安、比亚迪等车企相继官宣接入&#xff0c;掀起了“AI定义汽车”浪潮。 而这股最火的AI汽车热潮&#xff0c;除了深度赋能智能座舱、智能驾驶等AI竞争更白热化的细分场景&#xff0…