[bzoj3626][树链剖分]LCA

python实现序列比对之Needleman-wunsch算法 (附完整源码) 阅读详情

Description

给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。
设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。 有q次询问,每次询问给出l r
z,求sigma_{l<=i<=r}dep[LCA(i,z)]。 (即,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和)

Input

第一行2个整数n q。 接下来n-1行,分别表示点1到点n-1的父节点编号。 接下来q行,每行3个整数l r z。

Output

输出q行,每行表示一个询问的答案。每个答案对201314取模输出

Sample Input

5 2

0

0

1

1

1 4 3

1 4 2

Sample Output

8

5

HINT

共5组数据,n与q的规模分别为10000,20000,30000,40000,50000。

题解

好题,把思路反一下。
对于一个询问z,如果我们把root~z这一段全部改成1
那么实际上就是要找sigma l<=i<=r,root~i的sum值
为什么,因为z的lca一定在z到root这条链上,然后只需要找i到root与z到root的最长公共链即可
这个操作是可逆的,也就是说如果我们把i到root这一段+1,找z~root的sum值也可以诶
考虑离线
对于答案,可以发现拆成两段是可以的,即1~r这一段减去1~l-1这段
我们把1~n依次加入修改,当枚举到有询问左端点+1或者询问右端点在这个地方时,更新答案即可

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int mod=201314;
struct node
{
    int x,y,next;
}a[110000];int len,last[51000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int fa[51000],son[51000],tot[51000],dep[51000];
int n,m;
void pre_tree_node(int x)
{
    son[x]=0;tot[x]=1;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(y!=fa[x])
        {
            fa[y]=x;
            dep[y]=dep[x]+1;
            pre_tree_node(y);
            if(tot[y]>tot[son[x]])son[x]=y;
            tot[x]+=tot[y];
        }
    }
}
int ys[51000],z,top[51000];
void pre_tree_edge(int x,int tp)
{
    ys[x]=++z;top[x]=tp;
    if(son[x]!=0)pre_tree_edge(son[x],tp);
    for(int k=last[x];k;k=a[k].next)if(a[k].y!=fa[x] && a[k].y!=son[x])pre_tree_edge(a[k].y,a[k].y);
}
struct trnode
{
    int lc,rc,l,r,c;
    int lazy;
}tr[210000];int trlen;
void bt(int l,int r)
{
    int now=++trlen;
    tr[now].l=l;tr[now].r=r;
    tr[now].lc=tr[now].rc=-1;tr[now].c=tr[now].lazy=0;
    if(l<r)
    {
        int mid=(l+r)/2;
        tr[now].lc=trlen+1;bt(l,mid);
        tr[now].rc=trlen+1;bt(mid+1,r);
    }
}
void upd(int now)
{
    int lc=tr[now].lc,rc=tr[now].rc;
    int lsum=tr[lc].r-tr[lc].l+1,rsum=tr[rc].r-tr[rc].l+1;
    tr[lc].lazy+=tr[now].lazy;tr[rc].lazy+=tr[now].lazy;
    tr[lc].c+=lsum*tr[now].lazy;tr[rc].c+=rsum*tr[now].lazy;
    tr[now].lazy=0;
}
void change(int now,int l,int r)
{
    if(tr[now].l==l && tr[now].r==r)
    {
        tr[now].c+=(r-l+1);tr[now].lazy++;
        return ;
    }
    int lc=tr[now].lc,rc=tr[now].rc;
    int mid=(tr[now].l+tr[now].r)/2;
    if(tr[now].lazy)upd(now);
    if(r<=mid)change(lc,l,r);
    else if(mid+1<=l)change(rc,l,r);
    else change(lc,l,mid),change(rc,mid+1,r);
    tr[now].c=tr[lc].c+tr[rc].c;
}
int findsum(int now,int l,int r)
{
    if(tr[now].l==l && tr[now].r==r)return tr[now].c;
    int lc=tr[now].lc,rc=tr[now].rc;
    int mid=(tr[now].l+tr[now].r)/2;
    if(tr[now].lazy)upd(now);
    if(r<=mid)return findsum(lc,l,r);
    else if(mid+1<=l)return findsum(rc,l,r);
    else return findsum(lc,l,mid)+findsum(rc,mid+1,r);
}
void chmul(int x,int y)
{
    int tx=top[x],ty=top[y];
    while(tx!=ty)
    {
        if(dep[tx]>dep[ty])swap(tx,ty),swap(x,y);
        change(1,ys[ty],ys[y]);
        y=fa[ty];ty=top[y];
    }
    if(x==y){change(1,ys[x],ys[x]);return ;}
    else
    {
        if(dep[x]>dep[y])swap(x,y);
        change(1,ys[x],ys[y]);return ;
    }
}
int sol(int x,int y)
{
    int tx=top[x],ty=top[y],ans=0;
    while(tx!=ty)
    {
        if(dep[tx]>dep[ty])swap(tx,ty),swap(x,y);
        ans+=findsum(1,ys[ty],ys[y]);
        y=fa[ty];ty=top[y];
    }
    if(x==y){return ans+findsum(1,ys[x],ys[x]);}
    else
    {
        if(dep[x]>dep[y])swap(x,y);
        return ans+findsum(1,ys[x],ys[y]);
    }
}
struct ask
{
    int l,r,z,op;
    int prel,prer;
}A[51000];
bool cmp(ask n1,ask n2)
{
    if(n1.z!=n2.z)return n1.z<n2.z;
    if(n1.r!=n2.r)return n1.r>n2.r;
    return n1.l<n2.l;
}
int s[51000],answer[51000];
int prel[51000],prer[51000];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=2;i<=n;i++)
    {
        int x;
        scanf("%d",&x);x++;
        ins(x,i);
    }
    fa[1]=0;dep[1]=1;pre_tree_node(1);
    z=0;pre_tree_edge(1,1);
    trlen=0;bt(1,z);
    memset(prel,-1,sizeof(prel));memset(prer,-1,sizeof(prer));
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&A[i].l,&A[i].r,&A[i].z);A[i].l++,A[i].r++,A[i].z++,A[i].op=i;
        A[i].prel=prel[A[i].l];prel[A[i].l]=i;
        A[i].prer=prer[A[i].r];prer[A[i].r]=i;
    }
    for(int i=1;i<=n;i++)
    {
        chmul(i,1);
        if(prel[i+1]!=-1)
        {
            int p=prel[i+1];
            while(p!=-1)
            {
                answer[A[p].op]-=sol(A[p].z,1);
                p=A[p].prel;
            }
        }
        if(prer[i]!=-1)
        {
            int p=prer[i];
            while(p!=-1)
            {
                answer[A[p].op]+=sol(A[p].z,1);
                p=A[p].prer;
            }
        }
    }
    for(int i=1;i<=m;i++)printf("%d\n",answer[i]%mod);
    return 0;
}
CUDA内核反汇编实战:用cuobjdump解锁SASS指令的奥秘 本文详细介绍了CUDA内核与SASS指令的关系,以及使用cuobjdump工具进行反汇编分析的方法。主要内容包括:1. CUDA内核的基本概念及其在GPU并行计算中的重要性;2. SASS指令作为底层汇编指令的关键作用;3. cuobjdump工具的安装配置和使用方法;4. 通过数组加法实例演示反汇编过程;5. 深入分析SASS指令格式、分类和执行流程;6. 两个实际案例展示性能优化和问题排查的应用。文章为开发者提供了深入理解CUDA程序底层执行机制的有效途径。 阅读详情

相关推荐

Vim 入门到够用:Linux 文本编辑器的三种模式、常用操作与实战技巧

i 进入编辑模式Esc 退出编辑模式回到命令模式: 从命令模式进入底行模式编辑,不一定非得“打开就直接打字”。一旦你接受了“模式”这件事,后面很多操作都会顺起来。学 Vim,不要追求一次学全,先把“命令模式—编辑模式—底行模式”这条主线练熟。只要这条主线通了,后面的复制、删除、搜索、替换,都是顺手补上去的能力。

Web安全工具库 798

树链剖分学习&BZOJ1036

题目传送门 树链剖分,计算机术语,指一种对树进行划分的算法,它先通过轻重边剖分将树分为多条链,保证每个点属于且只属于一条链,然后再通过数据结构(树状数组、SBT、SPLAY、线段树等)来维护每一条链。 以下是几种概念: 常见的路径剖分的方法是轻重树链剖分(启发式剖分) 将树中的边分为:轻边和重边 ž定义size(X)为以X为根的子树的节点个数。 ž令V为U的儿子节点中...

ald28060的博客 166

模拟IC版图DRC实战:手把手教你搞定MIM电容天线错误和ESD.10g违例

本文深入解析模拟IC版图中的MIM电容天线错误和ESD.10g违例问题,提供从错误解码到实战修复的完整指南。通过电路图修改、版图优化和验证闭环等步骤,帮助工程师高效解决DRC错误,特别适用于ADC等精密模拟电路设计。文章还分享了高级排错技巧和预防性设计策略,大幅提升流片成功率。

weixin_27697385的博客 295

BZOJ 4034浅谈树链剖分及线段树维护

世界真的很大 这道题还是很良心的 上来就说是数据结构的题 这类题的特点是代码量大,叙述简单,支持修改和查询,数据规模在10^5左右 还是先看一下题: description:有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a 。 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。 操作 3 :询

BerryKanry的博客 571

别再乱调栅极电阻了!手把手教你用示波器调试FOC驱动MOS管,避开EMC和震荡坑

本文详细介绍了FOC驱动中MOS管栅极参数的精准调试方法,涵盖示波器配置、波形特征分析及栅极电阻选型策略。通过实战案例和工程经验,帮助工程师有效解决EMC和震荡问题,提升驱动电路稳定性和效率。

weixin_28728495的博客 502

【100分】最长子字符串的长度

题目要求在一个环形字符串中找出字符 ‘o’ 出现了偶数次的最长子字符串长度。这里的字符串是一个环形的,即首尾相连。代码统计了字符串中字符 ‘o’ 的出现次数,并根据其奇偶性返回相应的最长子字符串长度。当 ‘o’ 的数量为偶数时,直接返回字符串长度;当 ‘o’ 的数量为奇数时,返回长度减去 1。给你一个字符串 s,字符串s首尾相连成一个环形 ,请你在环中找出 ‘o’ 字符出现了偶数次最长子字符串的长度。【最长子字符串的长度】

weixin_54707168的博客 896

bzoj4326 树链剖分 + 线段树 // 二分 lca + 树上差分

https://www.lydsy.com/JudgeOnline/problem.php?id=4326 题意:N个点的树上给M条树链,问去掉一条边的权值之后所有树链长度和的最大值最小是多少。 首先想到去掉的树边一定是最长链上的树边,所以产生的思路就是寻找出一条询问里的最长链之后依次枚举上面所有的边,询问去掉这条边之后其余所有边的最大值。 由于N和M都在30W,直接暴力肯定不...

weixin_30329623的博客 154

计算机视觉论文复现指南:从理论到可运行代码的保姆级教程

计算机视觉论文复现指南:从理论到可运行代码的保姆级教程​ ,人工智能,计算机视觉,大模型,AI,本文围绕计算机视觉论文复现展开,介绍从理论到可运行代码的全流程。先强调复现的重要性,再讲解复现前的准备,包括明确目标、构建工具链;接着说明代码获取分析、环境配置调优、调试运行技巧及结果验证优化方法,还推荐了高效工具,提及复现中的伦理规范。旨在助读者掌握复现方法论,实现从经典模型到前沿论文的复现,推动学术成果落地。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 12万+

bzoj 2836 魔法树 —— 树链剖分

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2836 树链剖分裸题; 写码五分钟,调码两小时,RE不断,狂交二十五遍,终于找到一处小细节——易错点! 就是跳 top 时,不是按 dep[x] < dep[y] 交换 x,y,而要按 dep[top[x]] < dep[top[y]] 交换 x,y,否则就跳不到 ...

aodan5477的博客 191

混响效果的编程实现:Schroeder混响模型与Moorer型混响

Schroeder混响模型是由Manfred R. Schroeder在1962年提出的,它基于一系列串联的反射器(Allpass Comb Filters)和并联的反射器(Feedback Comb Filters)构成。Schroeder混响模型是由Manfred R. Schroeder在1962年提出的,它基于一系列串联的反射器(Allpass Comb Filters)和并联的反射器(Feedback Comb Filters)构成。通过调整各个反射器和全通滤波器的参数,可以实现不同的混响效果。

2301_79326857的博客 1082

第1集:面试官视角:AIOps 核心能力模型与面试项目全局搭建【免费试读】

本文介绍了一门面向AIOps工程师的面试实战课程,针对当前运维领域薪资差距明显的痛点,帮助学员系统掌握企业级AIOps平台开发能力。课程承诺提供可直接用于面试和生产环境的代码实现,从零构建模块化AIOps平台。第一集重点讲解了面试官视角下的核心能力模型,并指导学员搭建项目基础环境,包括Python虚拟环境配置、本地大模型部署(Ollama)以及智能巡检Agent的代码实现。课程强调实战导向,通过40集系统讲解,帮助学员实现薪资40-60万的职业跃升。

qq_2937655951的博客 615

3626: [LNOI2014]LCA LCT

神题..我太弱了不会做.. 以下是我复制的ws_yzy神犇复制的PoPoQQQ大爷复制gconeice的题解 显然,暴力求解的复杂度是无法承受的。 考虑这样的一种暴力,我们把 z 到根上的点全部打标记,对于 l 到 r 之间的点,向上搜索到第一个有标记的点求出它的深度统计答案。观察到,深度其实就是上面有几个已标记了的点(包括自身)。所以,我们不妨把 z 到根的路径上的点全部 +1,对于

ws_fqk 738

RT-DETR-R18 上下文信息融合:引入全局特征提升遮挡目标检测

"""轻量化全局特征提取器(2层Transformer编码器)"""# 特征投影层(将多尺度特征统一维度)# 轻量化Transformer编码器(分组卷积优化)# 全局特征池化(输出 [bs, hidden_dim])# local_features: 多尺度特征列表 [C3, C4, C5],各 [bs, c, h, w]# 统一投影至 hidden_dim 并展平为序列# Transformer编码全局上下文# 全局池化得到全局向量。

走向CTO的路上... 495

BZOJ 3626 LCA 树链剖分

题目链接:bzoj3626 题目大意:给出一个有根数,对于询问l,r,z,求出求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和 题解: 引用清华爷gconeice的题解 显然,暴力求解的复杂度是无法承受的。 考虑这样的一种暴力,我们把 z 到根上的点全部打标记,对于 l 到 r 之间的点,向上搜索到第一个有标记的点求出它的深度统计答案。观察到,深度其实就是

Cabinfever的专栏 353

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

bzoj3626 LCA 树链剖分

难得有一道从头到尾自己做的题了T_T(←这么弱还好意思说)。        首先考虑一个特定的询问(x,z)应该怎么做:将所有1...x的点到根的路径覆盖一遍,然后就是求z到根的每一条边的覆盖次数的和。(画个图就很明确了)。        于是可以将询问(l,r,z)拆成(r,z)和(l-1,z),然后按照第一维排序(注意特判0的情况)。        然后将x从1循环到n,每次将x到根的路

lych的博客 728

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

【BZOJ3626】LCA(树链剖分,Link-Cut Tree)

【BZOJ3626】LCA(树链剖分,Link-Cut Tree) 题面 Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。 有q次询问,每次询问给出l r z,求sigma_{l<=i<=r}dep[LCA(i,z)]。 (即,求在[l,...

weixin_30407099的博客 194

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

[bzoj3626][LNOI2014]LCA 树链剖分

3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MB [Submit][Status][Discuss] Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。 有q次询问

Unlimited Code Works 377

BZOJ 3626 [LNOI2014]LCA 树链剖分 离线+差分

3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 767  Solved: 263 [Submit][Status][Discuss] Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。 设dep[i]表示点i的深度,LC

Aosaki 600

【BZOJ 3626】【LNOI 2014】LCA【树链剖分】

Description给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。 有q次询问,每次询问给出l r z,求sigma_{l<=i<=r}dep[LCA(i,z)]。 (即,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和)Input第一行2个整数n q。

cyclization的小栈 387

BZOJ3626 LCA 【树链剖分+线段树】

题目描述: 给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。 有q次询问,每次询问给出l r z,求∑l&amp;lt;=i&amp;lt;=rdep[LCA(i,z)]\sum_{l&amp;lt;=i&amp;lt;=r}dep[LCA(i,z)]∑l&lt;=i&lt...

Master.Yi的博客 340

bzoj 3626 LCA (树链剖分)

题意:思路:比较有意思的树链剖分 首先对于两个点lca的深度,我们发现就是两点和根的连线的重叠部分,那么我们就可以先把一个点到根的所有点都染下色,再用另一个点去查看到根有几个点被染色了 然后想怎么处理那么多区间,根据之前说的,我们可以把[l,r]中所有的点都看作第一个点,z看作第二个点,这样我们离线了提问,然后一边把点放进去一边查询即可错误及反思:l是可以为0的,bzoj有时候数据不会给的很细致

Roll_Keyboard的博客 320

bzoj3626 [LNOI2014]LCA——树链剖分

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3626 思路很巧妙,把区间换成前缀和相减; 把 l ~ r 到根路径上的点的点权都+1,然后 z 到根求和,就是 z 与 l ~ r 每个点 lca 深度的和; 这里若要用前缀和,则需要把询问离线排序; 然后上树链剖分,修改和求和线段树解决即可。 代码如下: #in...

aodan5477的博客 200

【BZOJ3626】LCA(树链剖分)

优美的一道题~

AFO 394

bzoj3626: [LNOI2014]LCA 树链剖分

bzoj3626: [LNOI2014]LCA Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。 有q次询问,每次询问给出l r z,求sigma_{l&lt;=i&lt;=r}dep[LCA(i,z)]。 (即,求在[l,r]区间内的...

maxtir的博客 368

bzoj 3626: [LNOI2014]LCA 树链剖分

题意给出一个n个节点的有根树(编号为0到n-1,根节点为0)。一个点的深度定义为这个节点到根的距离+1。 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先。 有q次询问,每次询问给出l r z,求∑l<=i<=rdep[LCA(i,z)]。\sum_{l<=i<=r}dep[LCA(i,z)]。 (即,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和) n,

beginend 420

BZOJ3626 LNOI2014 LCA 树链剖分

题意:给定一棵树,每次询问给出l r z,求在[l,r]区间内的每个节点i与z的最近公共祖先的深度之和 题解: 显然,暴力求解的复杂度是无法承受的。 考虑这样的一种暴力,我们把 z 到根上的点全部打标记,对于 l 到 r 之间的点,向上搜索到第一个有标记的点求出它的深度统计答案。观察到,深度其实就是上面有几个已标记了的点(包括自身)。所以,我们不妨把 z 到根的路径上的点全部 +1...

a18700013354的博客 161
上一篇: [bzoj1965][数论]SHUFFLE 洗牌
下一篇: [bzoj3875][DP][最短路]骑士游戏
Rose_max
博客等级 码龄10年 97粉丝 610原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值