LCA 各种神奇的LCA优化方法

LCA(Least Common Ancestors)

树上问题的一种。

朴素lca很简单啦,我就不多说了,时间复杂度n^2

1.倍增LCA

时间复杂度 nlongn+klogn

其实是一种基于朴素lca的优化方法,

朴素lca只能一层层的向上查询,而这个有一定状态压缩的想法

即每一次跳2^i层,让O(n)的查找变成O(logn)。

以上就是我对倍增lca的理解。

以洛谷P3128为例,

[USACO15DEC]最大流Max Flow

题目描述

Farmer John has installed a new system of N-1N?1 pipes to transport milk between the NN stalls in his barn (2 \leq N \leq 50,0002≤N≤50,000), conveniently numbered 1 \ldots N1…N. Each pipe connects a pair of stalls, and all stalls are connected to each-other via paths of pipes.

FJ is pumping milk between KK pairs of stalls (1 \leq K \leq 100,0001≤K≤100,000). For the iith such pair, you are told two stalls s_is?i?? and t_it?i??, endpoints of a path along which milk is being pumped at a unit rate. FJ is concerned that some stalls might end up overwhelmed with all the milk being pumped through them, since a stall can serve as a waypoint along many of the KKpaths along which milk is being pumped. Please help him determine the maximum amount of milk being pumped through any stall. If milk is being pumped along a path from s_is?i?? to t_it?i??, then it counts as being pumped through the endpoint stalls s_is?i?? and

t_it?i??, as well as through every stall along the path between them.

FJ给他的牛棚的N(2≤N≤50,000)个隔间之间安装了N-1根管道,隔间编号从1到N。所有隔间都被管道连通了。

FJ有K(1≤K≤100,000)条运输牛奶的路线,第i条路线从隔间si运输到隔间ti。一条运输路线会给它的两个端点处的隔间以及中间途径的所有隔间带来一个单位的运输压力,你需要计算压力最大的隔间的压力是多少。

输入输出格式

输入格式:

The first line of the input contains NN and KK.

The next N-1N?1 lines each contain two integers xx and yy (x \ne yx≠y) describing a pipe

between stalls xx and yy.

The next KK lines each contain two integers ss and tt describing the endpoint

stalls of a path through which milk is being pumped.

输出格式:

An integer specifying the maximum amount of milk pumped through any stall in the

barn.

差分数组+倍增LCA

先DFS建树,再倍增求lca,最后在求lca时维护一个sum数组(表示被遍历的次数),最后再一遍dfs求出最大被遍历次数

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
#define N 100001
int n,K;
struct node
{
    int to,next;
}e[N];
int ans;
int dep[N],fa[N][32],head[N],cnt,sum[N];
void add(int x,int y)
{
    e[cnt].to=y;
    e[cnt].next=head[x];
    head[x]=cnt++;
    return ;
}
void init()
{
    memset(head,-1,sizeof(head));
    return ;
}
void dfs(int x,int from)
{
    dep[x]=dep[from]+1;
    fa[x][0]=from;
    for(int i=head[x];i!=-1;i=e[i].next)
    {
        if(e[i].to!=from)
        {
            dfs(e[i].to,x);
        }
    }
    return ;
}
int lca(int x,int y)
{
    if(dep[x]<dep[y])
    {
        swap(x,y);
    }
    int dep1=dep[x]-dep[y];
    for(int i=0;i<=20;i++)
    {
        if((dep1&(1<<i))!=0)
        {
            x=fa[x][i];
        }
    }
    if(x==y)
    {
        return x;
    }
    for(int i=20;i>=0;i--)
    {
        if(fa[x][i]!=fa[y][i])
        {
            x=fa[x][i];
            y=fa[y][i];
        }
    }
    return fa[x][0];
}
void renew(int x)
{
    for(int i=head[x];i!=-1;i=e[i].next)
    {
        int to1=e[i].to;
        if(to1!=fa[x][0])
        {
            renew(to1);
            sum[x]+=sum[to1];
        }
    }
    ans=max(ans,sum[x]);
    return ;
}
int main()
{
    init();
    scanf("%d%d",&n,&K);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    dep[1]=1;
    dfs(1,0);
    for(int i=1;i<=20;i++)
    {
        for(int j=1;j<=n;j++)
        {
            fa[j][i]=fa[fa[j][i-1]][i-1];
        }
    }
    for(int i=1;i<=K;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        int z=lca(x,y);
        sum[z]--;
        sum[fa[z][0]]--;
        sum[x]++;
        sum[y]++;
    }
    renew(1);
    printf("%d\n",ans);
    return 0;
}

明天继续更新,今天先写到这里...

2.离线tarjan_lca

3.树链剖分_lca

题目描述

Farmer John has installed a new system of N-1N?1 pipes to transport milk between the NN stalls in his barn (2 \leq N \leq 50,0002≤N≤50,000), conveniently numbered 1 \ldots N1…N. Each pipe connects a pair of stalls, and all stalls are connected to each-other via paths of pipes.

FJ is pumping milk between KK pairs of stalls (1 \leq K \leq 100,0001≤K≤100,000). For the iith such pair, you are told two stalls s_is?i?? and t_it?i??, endpoints of a path along which milk is being pumped at a unit rate. FJ is concerned that some stalls might end up overwhelmed with all the milk being pumped through them, since a stall can serve as a waypoint along many of the KKpaths along which milk is being pumped. Please help him determine the maximum amount of milk being pumped through any stall. If milk is being pumped along a path from s_is?i?? to t_it?i??, then it counts as being pumped through the endpoint stalls s_is?i?? and

t_it?i??, as well as through every stall along the path between them.

FJ给他的牛棚的N(2≤N≤50,000)个隔间之间安装了N-1根管道,隔间编号从1到N。所有隔间都被管道连通了。

FJ有K(1≤K≤100,000)条运输牛奶的路线,第i条路线从隔间si运输到隔间ti。一条运输路线会给它的两个端点处的隔间以及中间途径的所有隔间带来一个单位的运输压力,你需要计算压力最大的隔间的压力是多少。

输入输出格式

输入格式:

The first line of the input contains NN and KK.

The next N-1N?1 lines each contain two integers xx and yy (x \ne yx≠y) describing a pipe

between stalls xx and yy.

The next KK lines each contain two integers ss and tt describing the endpoint

stalls of a path through which milk is being pumped.

输出格式:

An integer specifying the maximum amount of milk pumped through any stall in the

barn.

输入输出样例

输入样例#1:

5 10
3 4
1 5
4 2
5 4
5 4
5 4
3 5
4 3
4 3
1 3
3 5
5 4
1 5
3 4

输出样例#1:

9
时间: 2024-12-13 20:24:27

LCA 各种神奇的LCA优化方法的相关文章

tarjan求lca的神奇

题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每行包含两个正整数x.y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树). 接下来M行每行包含两个正整数a.b,表示询问a结点和b结点的最近公共祖先. 输出格式: 输出包含M行,每行包含一个正整数,依次为每一个询问的结果. 输入输出样例 输入样例#1: 5 5 4 3 1 2 4 5

深度学习之(十一)Deep learning中的优化方法:随机梯度下降、受限的BFGS、共轭梯度法

Deep learning中的优化方法 三种常见优化算法:SGD(随机梯度下降),LBFGS(受限的BFGS),CG(共轭梯度法). 1.SGD(随机梯度下降) 随机梯度下降(Stochastic Gradient Descent, SGD)是随机和优化相结合的产物,是一种很神奇的优化方法,属于梯度下降的一种,适用于大规模问题. 要想扯清楚它,还得先谈谈梯度下降.众所周知,每个优化问题都会有一个目标函数F(w)F(w),梯度下降采用迭代的策略,从初始点w0w0开始,每次沿着目标函数在当前点的负梯

垃圾邮件过滤优化方法

垃圾邮件过滤优化方法 通过honeypot project 搜集大量垃圾邮件数据 通过解析邮件header 获取垃圾邮件发送路径和服务器相关信息 对编写错误的单词的修正 比如:w4tch 对相同含义的词进行归类处理,比如:discount 和discounts   (可以通过porter stemmer,下面就是该算法c语言的一种实现) /* This is the Porter stemming algorithm, coded up in ANSI C by the author. It m

Linux网络性能优化方法简析

Linux网络性能优化方法简析 2010-12-20 10:56 赵军 IBMDW 字号:T | T 性能问题永远是永恒的主题之一,而Linux在网络性能方面的优势则显而易见,这篇文章是对于Linux内核中提升网络性能的一些优化方法的简析,以让我们去后台看看魔术师表演用的盒子,同时也看看内核极客们是怎样灵活的,渐进的去解决这些实际的问题. AD:2014WOT全球软件技术峰会北京站 课程视频发布 对于网络的行为,可以简单划分为 3 条路径:1) 发送路径,2) 转发路径,3) 接收路径,而网络性

Caffe学习系列(8):solver优化方法

上文提到,到目前为止,caffe总共提供了六种优化方法: Stochastic Gradient Descent (type: "SGD"), AdaDelta (type: "AdaDelta"), Adaptive Gradient (type: "AdaGrad"), Adam (type: "Adam"), Nesterov’s Accelerated Gradient (type: "Nesterov&qu

php-fpm优化方法 pm.min_spare_servers、pm.max_spare_servers 的真实意义

php-fpm 进程池优化方法 php-fpm进程池开启进程有两种方式,一种是static,直接开启指定数量的php-fpm进程,不再增加或者减少:另一种则是dynamic,开始时开启一定数量的php-fpm进程,当请求量变大时,动态的增加php-fpm进程数到上限,当空闲时自动释放空闲的进程数到一个下限.这两种不同的执行方式,可以根据服务器的实际需求来进行调整. 要用到的一些参数,分别是pm.pm.max_children.pm.start_servers.pm.min_spare_serve

30多条mysql数据库优化方法,千万级数据库记录查询轻松解决【转】

转自:http://www.ihref.com/read-16422.html 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描, Sql 代码 : select id from t where num is null; 可以在 num 上设置默认值 0,确保表中 num 列没有 null 值,然后这样查询: Sql 代码 : s

mark---[mysql多表关联查询的优化方法]

对于一个网站来说,数据库的结构至关重要.即要利于存储(入库不阻塞),又要利于查询(查询不锁表).网站数据库优化经验是一个积累的过程.下面就对多表关联查询的优化方法,举例说明. 现在社区分享类网站很火,就拿方维购物分享网站举例说明吧.也是对二次开发方维购物分享网站的一点总结,高手可以飞过. 购物分享的关键表有:分享表.图片表.文件表.评论表.标签表.分类表等. 围绕分享的表就么多,哇,那也不少啊.当我们查看一个图片的详细信息时,就要显示以上表里的信息.显示图片所属的分类.给图片打的标签.图片的评论

【转载】数学之美番外篇:平凡而又神奇的贝叶斯方法

数学之美番外篇:平凡而又神奇的贝叶斯方法 BY 刘未鹏 – SEPTEMBER 21, 2008POSTED IN: 数学, 机器学习与人工智能, 计算机科学 概率论只不过是把常识用数学公式表达了出来. ——拉普拉斯 记得读本科的时候,最喜欢到城里的计算机书店里面去闲逛,一逛就是好几个小时:有一次,在书店看到一本书,名叫贝叶斯方法.当时数学系的课程还没有学到概率统计.我心想,一个方法能够专门写出一本书来,肯定很牛逼.后来,我发现当初的那个朴素归纳推理成立了——这果然是个牛逼的方法. ——题记 目