暑假第六周总结

  这周主要就是学习一些图论的算法了,先看博客,然后去洛谷找几个题实践一下。

        LCA:LCA问题我用倍增的算法多一些。以前好像比较少涉及到log2相关的一些东西,现在用的就比较多了。

倍增的大概思想就是给定两个点,度数较大的那个点先跳到与另一个点的度数相等的那个点,如果此时二者重合,返回这个点;如果不重合,那么就一直跳到这两个点LCA的前一个点,最后返回fa[x][0]。在跳的过程中,如果超过了lca(x,y),那么就不跳。最后一定可以到达目标点,因为目标点一定可以在二进制下被表示。

在处理LCA的问题时,洛谷上的一篇题解提到了一个常数优化的问题。

 for(int i=1;i<=n;i++){
        lg[i]=lg[i-1]+(1<<lg[i-1]==i);
    }//预先算出log2(i)+1的值。

        RMQ:不放在LCA里,单独列出来。在处理给你一个区间,找出这个区间的最小值的问题上特别好用(最大值同理)。dp[i][j]表示自i元素起,2^j个元素的最小值,即区间[i,i+2^j-1]。以前遇到这类问题,直接RMQ就完了。

直到遇到了这个题,这个题用RMQ会MLE(不加优化)。

求m区间内的最小值 - 洛谷

于是就有了一个叫单调队列的东西。声明一个deque,对于一个新的元素而言,如果队尾元素比它大,就一直弹出,直到比它小,插入队尾。在输出的时候,从对首开始查询,如果满足题意就输出,否则就弹出。

        树上差分:tmp数组记录点出现的次数。边差分:tmp[s]++,tmp[t]++,tmp[LCA(s,t)]-=2。

点差分:tmp[u]++,tmp[v]++,tmp[LCA(u,v)]–,tmp[fa[LCA(u,v)][0]]–。//记k=LCA(u,v)。回溯的时候,在(u,k)这条路径上每点加1,(v,k)这条路径上每点加1,现在k被加了两次,所以减去一次,此时k的父节点也要减一次,从而消除加1的影响。

        树的直径和树的重心:求树的直径时,先任选一个点,进行一次dfs,找出距它的最远点,再以最远点为起点,进行一次dfs,即可求出数的直径,即最长路。求树的重心时,利用的是在以树的重心为根节点时,最大子树的节点数最小的结论。只需要进行一次dfs,在求子树节点的时候随时更新。

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值