【瞎扯】树上差分的基本思路

         数据结构题中解法千变万化,但分析最近几年的趋势来看,有一种比较重要的思想->树上差分。(会树剖的大神不要嘲笑,虽然很多时候树剖都能很好解决QwQ)。至少,树上差分熟练的话还是可以解决很多问题的。这里就先分析两种基本的差分思路。

1.找被所有路径共同覆盖的边。

         可能这样讲不是很详细,那就看一道例题【Noip2015】运输计划(【Bzoj4326】)。大意是有许多条运输路径,让你在把一条边的用时不计的情况下找到最大路径的最短用时。看到这题很明显想到二分答案,而对于每一个答案,我们要记录超过此答案的计划。之后我们该怎么办呢,如果有一条边被所有计划共同覆盖,且去掉它(用时降为0)后能使得其中超答案时间最多的边都不超时,那便是可行答案。而我们就要来分析一下如何找这条边。

   首先我们除了一般的grand,depth等数组以外,多开两个数组:tmp和prev。tmp用来记录点的出现次数(具体点说实际上记录的是点到其父亲的边的出现次数),prev记录每个点到其父亲的那条边(这里根据题目记的权值,有必要时也可以记编号)。对于一条起点s,终点t的路径。我们这样处理:tmp[s]++,tmp[t]++,tmp[LCA(s,t)]-=2。(记住:最后要从所有叶结点把权值向上累加。)以一次操作为例,我们来看看效果(可以画一张图)。首先tmp[s]++,一直推上去到根,这时候s到root的路径访问次数都+1,tmp[t]++后,t到lca路径加了1,s到lca路径加了1,而lca到根的路径加了2。这时,我们只需要tmp[LCA(s,t)]-=2,推到根,就能把那些多余的路径减掉,达到想要的目的。而这是一次操作,对于很多次操作的话,我们只需要维护tmp,而不必每次更新到根,维护好tmp最

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值