一种点分治树的写法

大意就是用 vector 直接记录

  1. 无需显式建出叶向树,只需记录 fa。
  2. dis 每个中只用记录 dep 个值,常数比 map 等小。
  3. 但是从上向下不太好做,加点删点是比较好做的。
void getsz(int u, int lst = 0) {
    mxsz[u] = 0; sz[u] = 1;
    for (int v : G[u]) if (!vis[v] && v != lst) {
        getsz(v, u);
        cmax(mxsz[u], sz[v]);
        sz[u] += sz[v];
    }
    cmax(mxsz[u], all - sz[u]);
    if (mn > mxsz[u]) mn = mxsz[u], rt = u;
}
void getdis(int u, int d, int lst) {
    dis[u].eb(d);
    for (int v : G[u]) if (!vis[v] && v != lst) {
        getdis(v, d + 1, u);
    }
}
void build(int u) {
    getsz(u);
    cnt[u] = _cnt_begin; _cnt_begin += sz[u] + 1;//这是那道题的一个桶
    getdis(u, 0, 0);
    vis[u] = 1;
    for (int v : G[u]) if (!vis[v]) {
        mn = 1e9, all = sz[v], rt = -1;
        getsz(v); fa[rt] = u;
        build(rt);
    }
}

练习题

posted @   SkyMaths  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示