2018年3月18日训练日记

本文深入讲解了LCA(最近公共祖先)算法的三种实现方法,包括tarjan算法、ST(RMQ)算法以及树上倍增算法,并提供了详细的代码示例。

500道题刚做了140道就开始做不动了。。。估计要凉。。。

还是先把LCA看完。。。(以下内容 by 路人黑的纸巾,写的十分详细)

LCA(Lowest Common Ancestors),即最近公共祖先 

在一棵树上,两个节点的深度最浅的公共祖先就是LCA (自己可以是自己的祖先) 

其实LCA的用途很广,我个人认为OI里用LCA最多的像是这样子的题: 
给你一棵树(或者是一个图求完MST的树,这种会比较常见)和树上的两点,找出这两点之间的路径的最大值或最小值或其他东东 

这时我们可以借助这两点的LCA作为中转点来轻松地解决这类题目

方法1:tarjan算法(离线)求LCA

方法2:ST(RMQ)算法(在线)求LCA

注意事项
dfs序的长度是2n−1,用dfsO(n)处理出r、deep和dfs序之后直接套上裸RMQ 
(线段树?差不多的……别在意这个)
设f[i][j]表示dfs序中j~j+2^i-1的点当中,deep值最小的是哪个点 即可

每次询问时间复杂度O(1),完美

附大佬代码:

#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

int n,_n,m,s;//_n是用来放元素进dfs序里,最终_n=2n-1

struct EDGE
{
    int to;
    EDGE* las;
}e[1000001];//前向星存边

EDGE* last[500001];
int sx[1000001];//顺序,为dfs序
int f[21][1000001];//用于ST算法
int deep[500001];//深度
int r[500001];//第一次出现的位置

int min(int x,int y)
{
    return deep[x]<deep[y]?x:y;
}

void dfs(int t,int fa,int de)
{
    sx[++_n]=t;
    r[t]=_n;
    deep[t]=de;
    EDGE*ei;
    for (ei=last[t];ei;ei=ei->las)
        if (ei->to!=fa)
        {
            dfs(ei->to,t,de+1);
            sx[++_n]=t;
        }
}

int query(int l,int r)
{
    if (l>r)
    {
        //交换 
        l^=r;
        r^=l;
        l^=r;
    }
    int k=int(log2(r-l+1));
    return min(f[k][l],f[k][r-(1<<k)+1]);
}

int main()
{
    scanf("%d%d%d",&n,&m,&s);
    int j=0,x,y;
    for (int i=1;i<n;++i)
    {
        scanf("%d%d",&x,&y);
        e[++j]={y,last[x]};
        last[x]=e+j;
        e[++j]={x,last[y]};
        last[y]=e+j;
    }
    dfs(s,0,0);
    //以下是ST算法
    for (int i=1;i<=_n;++i)f[0][i]=sx[i];
    int ni=int(log2(_n)),nj,tmp;
    for (int i=1;i<=ni;++i)
    {
        nj=_n+1-(1<<i);
        tmp=1<<i-1;
        for (j=1;j<=nj;++j)
            f[i][j]=min(f[i-1][j],f[i-1][j+tmp]);
    }
    //以下是询问,对于每次询问,可以O(1)回答
    while (m--)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",query(r[x],r[y]));
    }
}

方法3:树上倍增找LCA

在hihocoder上的最近公共祖先  一  暴力都WA  已经绝望

昨晚的小白月赛。。。还行吧,按理说应该AK,只是卡特兰数卡了一点时间,最后俩题没来得及看,难度中等偏下。

目测做够500道基本不可能了。。。

但是还是要努力做啊。。。


训练数据保存为deep_convnet_params.pkl,UI使用wxPython编写。卷积神经网络(CNN)是一种专门针对图像、视频等结构化数据设计的深度学习模型,在计算机视觉、语音识别、自然语言处理等多个领域有广泛应用。其核心设计理念源于对生物视觉系统的模拟,主要特点包括局部感知、权重共享、多层级抽象以及空间不变性。 **1. 局部感知与卷积操作** 卷积层是CNN的基本构建块,使用一组可学习的滤波器对输入图像进行扫描。每个滤波器在图像上滑动,以局部区域内的像素值与滤波器权重进行逐元素乘法后求和,生成输出值。这一过程能够捕获图像中的边缘、纹理等局部特征。 **2. 权重共享** 同一滤波器在整个输入图像上保持相同的权重。这显著减少了模型参数数量,增强了泛化能力,并体现了对图像平移不变性的内在假设。 **3. 池化操作** 池化层通常紧随卷积层之后,用于降低数据维度并引入空间不变性。常见方法有最大池化和平均池化,它们可以减少模型对微小位置变化的敏感度,同时保留重要特征。 **4. 多层级抽象** CNN通常包含多个卷积和池化层堆叠在一起。随着网络深度增加,每一层逐渐提取更复杂、更抽象的特征,从底层识别边缘、角点,到高层识别整个对象或场景,使得CNN能够从原始像素数据中自动学习到丰富的表示。 **5. 激活函数与正则化** CNN中使用非线性激活函数来引入非线性表达能力。为防止过拟合,常采用正则化技术,如L2正则化和Dropout,以增强模型的泛化性能。 **6. 应用场景** CNN在诸多领域展现出强大应用价值,包括图像分类、目标检测、语义分割、人脸识别、图像生成、医学影像分析以及自然语言处理等任务。 **7. 发展与演变** CNN的概念起源于20世纪80代,其影响力在硬件加速和大规模数据集出现后真正显现。经典模型如LeNet-5用于手写数字识别,而AlexNet、VGG、GoogLeNet、ResNet等现代架构推动了CNN技术的快速发展。如今,CNN已成为深度学习图像处理领域的基石,并持续创新。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值