树链剖分入门+博客推荐

树链剖分入门博客推荐

网上关于树链剖分的文章很多,自己在学习树链剖分的时候找到了几篇好的文章,代码规范,有图例。树链剖分的部分自己先挖个坑,以后再专门写个博客来总结。

博客推荐

博客一

推荐理由:每个函数完成后的结果都有相应的图例,可以自己模拟一下和图对应,加深对函数功能的理解。

博客二

推荐理由:完整的函数实现,树链剖分+线段树的完整代码。

博客三

推荐理由:代码规范,通俗易懂。

我的常用代码模板

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+7;
struct node{
    int l, r;
    int ans, lazy;
}
struct edge{
    int to, next;
}e[maxn<<1];
int head[maxn], len;
int son[maxn], size[maxn], dep[maxn], fa[maxn];
int top[maxn], inp[maxn], cnt;
void init()
{
    len=cnt=0;
    for(int i=0; i<=n; i++)
        head[i]=-1;
}
void add(int u, int v)
{
    e[len].to=v;
    e[len].next=head[u];
    head[u]=len++;
}
  1. dfs1主要是解决树上点的基本信息
void dfs1(int u, int f, int depth)
{
    size[u]=1;
    dep[u]=pedth;
    fa[u]=f;
    for(int i=head[u]; i!=-1; i=e[i].next)
    {
        int v=e[i].to;
        if(v==f) continue;
        dfs1(v, u, depth+1);
        size[u]+=size[v];
        if(size[v] > size[son[u]])
            son[u]=v;
    }
}
  1. dfs2是处理dfs序和重链
void dfs2(int u, int tp)
{
    top[u]=tp;
    in[u]=++cnt;
    if(!son[u])
        return;
    dfs2(son[u], tp);
    for(int i=head[u]; i!=-1; i=e[i].next)
    {
        int v=e[i].to;
        if(v==son[u] || v==f[u])
            continue;
        dfs2(v, v);
    }
}
  1. 处理x和y的最近公共祖先
//fx表示x所在链的顶,fy表示y所在链的顶。
void lca(int x, int y)
{
    int fx=top[x], fy=top[y];
    while(fx!=fy)
    {
        if(dep[fx] < dep[fy]) //确保每次更新都是深度大的都是x
        {
            swap(x, y);
            swap(fx, fy);
        }
        x=fa[x];
        fx=top[x];
    }
    return dep[x] < dep[y] ? x:y;
}
  1. 把从x到y的一条最短链上点的值改为z
//把从x到y的最近链上点的值改为z;
void update_chain(int x, int y, int z)
{
    int fx=top[x], fy=top[y];
    while(fx!=fy)
    {
        if(dep[fx] < dep[fy])
        {
            swap(x, y);
            swap(fx, fy);
        }
        update(1, in[fx], in[x], z);
        //每往上跳一次,就修改以次经过路径上的值,因为DFS序中id[fx] < id[x],所以是区间[id[fx],id[x]];
    }
    if(in[x] > id[y]) 
        swap(x, y);
    update(1, in[x], in[y], z);
}
  1. 求从x到y的最近一条链点值的总和。
int query_chain(int x, int y)
{
    int ans=0, fx=top[x], fy=top[y];
    while(fx!=fy)
    {
        if(dep[fx] < dep[fy])
        {
            swap(x, y);
            swap(fx, fy);
        }
        ans+=query(1, in[fx], in[x]);
    }
    if(in[x] > in[y])
        swap(x, y);
    ans+=query(1, in[x], in[y]);
    return ans;
}

转载于:https://www.cnblogs.com/alking1001/p/11402131.html

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值