• 静态点分治学习笔记


    • 处理树上路径问题。
    • 填以前的坑。

    静态点分治。

    • 点分治的核心思想就是分治,每次选取树的重心把树分成两个部分。

    • 在这里,树的重心的定义是指以他为根,最大子树(sz)最小。

    • 然后每次划分就只考虑经过树的重心的路径。

    • 因为每次划分都至少把树分成一半,所以复杂度就是(log)了。

    • 得到重心:

    void Getroot(R i,R fm){
        sz[i]=1;R num=0;
        for(R k=hd[i];k;k=nt[k]){
            if(to[k]==fm||vis[to[k]])continue;
            Getroot(to[k],i),sz[i]+=sz[to[k]];
            num=max(num,sz[to[k]]);
        }
        num=max(num,tot-sz[i]);
        if(num<Max)Max=num,root=i;
    }
    
    • 注意这里的重心是划分出来的一个树,应该可以理解成一个联通块。
    • (vis)就是已经划分过的割点,不能走了。
    • (num)表示最大的子树,(tot)是这个子树大小。
    num=max(num,tot-sz[i]);
    
    • 注意到这一句,这个以这个点为根的子树最大值,是本来的子树大小,和联通块大小减去子树大小的最大值。
    • 然后所有的点取最小的点即可。

    第一种写法:

    • 跳点分治树:
    void Dfs(R i,R fm){
        sol(i,0,1),vis[i]=1;
        for(R k=hd[i];k;k=nt[k]){
            if(to[k]==fm||vis[to[k]])continue;
            sol(to[k],w[k],-1),tot=sz[to[k]],Max=inf;
            Getroot(to[k],0),Dfs(root,0);
        }
    }
    
    • (sol)的含义就是求解答案,每个题目不一样。
    • 因为现在的(i)一定是重心,(vis[i]=1)就相当于把树隔开了。
    • 然后枚举所有的儿子,再把一个儿子中的贡献减去。

    注意:

    • 我们考虑的是经过重心的路径,但是可以发现,对于一个重心(i),两个点在同一个子树内,那么路径是不会经过(i)的。然后我们单独把这个子树内的答案剪掉。注意,此时每个点的初始长度都是(w_k),这样才可以正确剪掉原来被重复统计的路径。
    • 然后初始化(tot),(Max),得到每一个子树根,然后再跳点分树。
    • 每一次统计答案可能要清空。
    • 例题 P2634 [国家集训队]聪聪可可

    第二种写法:

    • 对于最大值/最小值,不好删去重复的贡献(方案类问题是很好删除的,就是直接剪掉即可,但是最大值你不好删掉,因为不好维护次大值。)
    • 跳点分树
    void Dfs(R i){
        vis[i]=1;
        for(R k=hd[i];k;k=nt[k])
            if(!vis[to[k]])go(to[k],i,1,w[k]),let(to[k],i,1,w[k]);
        for(R k=hd[i];k;k=nt[k])
            if(!vis[to[k]])emp(to[k],i,w[k]);
        for(R k=hd[i];k;k=nt[k]){
            if(vis[to[k]])continue;
            tot=sz[to[k]],rt=0,Mx=n+1;
            Getrt(to[k],0),Dfs(rt);
        }
    }
    
    • 同样的,把树隔开。
    • 然后对于每一个子树,先考虑他和之前的点两两组合得到的答案((go)函数)
    • 然后在保存这个子树中一个答案产生的贡献((let)函数)
    • 最后清除筒((emp)函数)
    • 然后再分重心。
    • 例题:P4149 [IOI2011]Race

    题单:

  • 相关阅读:
    前后端不分离的springboot项目问题:页面框架问题
    SpringBoot使用Filter过滤器处理是否登录的过滤时,用response.sendRedirect()转发报错
    mysql千万级数据优化查询
    java进阶学习的一些思路
    java的List列表转成Tree(树形)结构列表
    cmd 一键获取 所有连接过的wifi 密码
    SQLMap用户手册【超详细】
    Python:SQLMAP参数中文解释
    初识sql注入及sqlmap
    wwwscan网站目录文件批量扫描工具
  • 原文地址:https://www.cnblogs.com/Tyher/p/9790459.html
Copyright © 2020-2023  润新知