【做题记录】P4211 [LNOI2014]LCA
P4211 [LNOI2014]LCA
题意
给出一个 \(n\) 个节点的有根树(编号为 \(0\) 到 \(n-1\),根节点为 \(0\))。
一个点的深度定义为这个节点到根的距离 \(+1\)。
设 \(dep[i]\) 表示点 \(i\) 的深度,\(LCA(i,j)\) 表示 \(i\) 与 \(j\) 的最近公共祖先。
有 \(m\) 次询问,每次询问给出 l r z
,求 \(\sum_{i=l}^r dep[LCA(i,z)]\)。
题解
我们考虑这样一件事情,就是说,两个点的 \(Lca\) 的深度的意义到底是什么,如何才能够快速求的?
在我们不会求 \(Lca\) 的时候,我们会将一个点一个一个往上爬,并将路径上的点染色。之后我们将另一个点暴力往上跳,第一个染色过的点就是 \(Lca\)。
我们考虑到这样一件事情,如果我们将一个点到根的路径上每个点数值加 \(1\),再求得另一个点到根的路径上的权值和,这不就是 \(Lca\) 的深度了吗?
于是求解一次询问就相当于对于 \(l\le x\le r\),将 \(x\) 到根的路径上每个点加一,最后答案就是 \(z\) 到根的权值和。
由于询问次数很多,不可能每次都这样处理一遍,考虑将询问拆开。
这样我们就可以在 \(O(n\log n)\) 复杂度内解决问题啦!
这就叫数据结构二步曲,学习一下,代码我现在放下。
#define Maxn 50005
#define pb push_back
#define mod 201314
typedef long long ll;
int n,m,tot,Time,cnt;
int ans[Maxn];
int dfn[Maxn],tp[Maxn],fa[Maxn],dep[Maxn],siz[Maxn],bigson[Maxn];
int hea[Maxn],nex[Maxn],ver[Maxn];
struct TREE { int laz,sum; }tree[Maxn<<2];
struct Query { int num,z,opt; };
vector<Query> q[Maxn];
void dfs1(int x)
{siz[x]=1;for(int i=hea[x];i;i=nex[i]){fa[ver[i]]=x,dep[ver[i]]=dep[x]+1;dfs1(ver[i]),siz[x]+=siz[ver[i]];if(siz[ver[i]]>siz[bigson[x]]) bigson[x]=ver[i];}
}
void dfs2(int x,int T)
{tp[x]=T,dfn[x]=++Time;if(bigson[x]) dfs2(bigson[x],T);for(int i=hea[x];i;i=nex[i]){if(ver[i]==bigson[x]) continue;dfs2(ver[i],ver[i]);}
}
void pushdown(int p,int nl,int nr)
{int mid=(nl+nr)>>1;tree[p<<1].laz=(tree[p<<1].laz+tree[p].laz)%mod;tree[p<<1|1].laz=(tree[p<<1|1].laz+tree[p].laz)%mod;tree[p<<1].sum=(tree[p<<1].sum+1ll*tree[p].laz*(mid-nl+1)%mod)%mod;tree[p<<1|1].sum=(tree[p<<1|1].sum+1ll*tree[p].laz*(nr-mid)%mod)%mod;tree[p].laz=0;
}
void add(int p,int nl,int nr,int l,int r)
{if(nl>=l && nr<=r) { tree[p].laz++,tree[p].sum+=(nr-nl+1); return; }pushdown(p,nl,nr);int mid=(nl+nr)>>1;if(mid>=l) add(p<<1,nl,mid,l,r);if(mid<r) add(p<<1|1,mid+1,nr,l,r);tree[p].sum=(tree[p<<1].sum+tree[p<<1|1].sum)%mod;
}
int query(int p,int nl,int nr,int l,int r)
{if(nl>=l && nr<=r) return tree[p].sum;pushdown(p,nl,nr);int mid=(nl+nr)>>1,ret=0;if(mid>=l) ret=(ret+query(p<<1,nl,mid,l,r))%mod;if(mid<r) ret=(ret+query(p<<1|1,mid+1,nr,l,r))%mod;tree[p].sum=(tree[p<<1].sum+tree[p<<1|1].sum)%mod;return ret;
}
inline void add_path(int x)
{while(tp[x]!=tp[1]) add(1,1,n,dfn[tp[x]],dfn[x]),x=fa[tp[x]];add(1,1,n,dfn[1],dfn[x]);
}
inline int query_path(int x)
{int ret=0;while(tp[x]!=tp[1]) ret=(ret+query(1,1,n,dfn[tp[x]],dfn[x]))%mod,x=fa[tp[x]];ret=(ret+query(1,1,n,dfn[1],dfn[x]))%mod;return ret;
}
inline void add_edge(int x,int y){ ver[++tot]=y,nex[tot]=hea[x],hea[x]=tot; }
int main()
{n=rd(),m=rd();for(int i=2,f;i<=n;i++) f=rd()+1,add_edge(f,i);dfs1(1),dfs2(1,0); // 记得输入的下标从 0 开始 for(int i=1,l,r,z;i<=m;i++){l=rd()+1,r=rd()+1,z=rd()+1;q[l-1].pb((Query){i,z,-1});q[r].pb((Query){i,z,1});}for(int i=1;i<=n;i++){add_path(i);for(Query j:q[i])ans[j.num]=(ans[j.num]+j.opt*query_path(j.z)%mod+mod)%mod;}for(int i=1;i<=m;i++) printf("%d\n",ans[i]);return 0;
}
【做题记录】P4211 [LNOI2014]LCA相关推荐
- P4211 [LNOI2014]LCA(离线 + 在线 做法)
P4211 [LNOI2014]LCA 有一棵根节点为111树,有mmm次询问,每次给定l,r,zl, r, zl,r,z,输出∑i=lrdep[lca(i,z)]\sum\limits_{i = l ...
- Regional 做题记录 (50/50)
写在前面 博主深感自己太弱了QAQ 于是有了一个刷水的想法,Regional的题目还是有很多考查思维的题目,所以这次是乱做50道思考题,可能会顺带做一些水题,这些题的简要题解会写到这篇博文里面,希望能 ...
- 2020.7月做题记录
转眼就到了2020的下半年了-前方仍是一片茫然. 长期计划 prufer 序列 2020.07.02-2020.07.04 Problem Finished P2624 [HNOI2008]明明的烦恼 ...
- 做题记录 To 2019.2.13
2019-01-18 4543: [POI2014]Hotel加强版:长链剖分+树形dp. 3653: 谈笑风生:dfs序+主席树. POJ 3678 Katu Puzzle:2-sat问题,给n个变 ...
- 退役前的做题记录1.0
退役前的做题记录1.0 租酥雨最近很懒qwq,具体表现在写题的时候不想发题解了. 但是想想这样也不太好,就决定发个一句话(半句话到几句话不等)题解上来. 2018-09.18-2018-09.28 [ ...
- 退役前的做题记录2.0
退役前的做题记录2.0 最近在刷省选题......大致上是按照省份刷的. 不过上面的题目顺序是按照写题的顺序排列的,所以可能会有点乱哈. [BZOJ2823][AHOI2012]信号塔 最小圆覆盖,随 ...
- 概率期望题(期望 DP)做题记录
概率期望题(期望 DP)做题记录 P3830 [SHOI2012]随机树 难点在于第二问:生成树的期望深度. 不 wei zhuo 捏,设 \(dp_{i,j}\) 表示已经有了 \(i\) 个叶子结 ...
- 数数题(计数类 DP)做题记录
数数题(计数类 DP)做题记录 CF1657E Star MST 我们称张无向完全图是美丽的当且仅当:所有和 \(1\) 相连的边的边权之和等于这张完全图的最小生成树的边权之和. 完全图点数为 \(n ...
- CSDN 第六期编程竞赛做题记录
CSDN 第六期编程竞赛做题记录 -- CSDN编程竞赛报名地址:https://edu.csdn.net/contest/detail/16 9.18周日闲来无视写一下 csdn 的编程题,每期编程 ...
最新文章
- 这次的人工智能是“有用”的人工智能
- Qt5.1.1 + VS2010安装错误(Unable to find a Qt build)
- 浅谈 iOS 版本号
- elastic search2.3.1(3) 查询语句拼接实战termQuery ,matchQuery, boolQuery, rangeQuery, wildcardQuery...
- 解析金融反欺诈技术的应用与实践
- PHP提取字符串中的数字
- Asp.net中的HttpModule和HttpHandler的简单用法
- [转载]创建数据库与完成数据添删改查--第一种写法
- 算法训练 纪念品分组(java)
- 【STM32】HAL库 STM32CubeMX教程十---DAC
- Android之深入WebView
- JSP中contentType和pageEncoding的区别
- 系统运维哪些事儿之正常状态
- kubernetes endpoints是什么
- 大学计算机基础教程第9章计算机多媒体技术
- 开源网络爬虫程序(spider)一览
- PHP中 逗号,和句号.的区别
- php接入支付宝app支付接口,php支付宝App支付生成预支付订单(统一下单接口)
- Apple iPhone 8G手机误升级至2.0降级破解日记
- 华为手机开启开发者模式
热门文章
- html 输入框自动缩短 一行内显示,JQuery UI组合框自动补全功能改进版(即时全部显示+input内容保存)...
- 登录服务器修改数据库吗,如何修改服务器登录数据库 sa
- 2021福建计算机会考操作题,2021年福建省信息技术会考笔试试题答案.doc
- mysql100链接同时处理_php 连接MYSQL 两个同时连接为什么只有一个连接成功,必须删掉一个,另外一个才查询生效出结果,下附代码...
- 还不会ts?一文带你打开ts的大门
- ciclop读音,购机必备,15种 3D扫描 设备 优缺点汇总
- java jlist 图标_java – 将图像添加到JList项目
- [C++11]指针空值类型nullptr
- 蓝桥杯2017初赛-分巧克力-二分
- 二叉搜索树(创建,插入,删除):基础篇,适合新手观看。