首页 > 其他分享 >P4211 [LNOI2014]LCA

P4211 [LNOI2014]LCA

时间:2023-05-03 11:55:30浏览次数:50  
标签:int text LNOI2014 maxson dfn P4211 res LCA

\(\color{purple}\text{P4211 [LNOI2014]LCA}\)

解题方法

可以发现一个结论:两个点到根节点的重合路径的长度即为他们 \(LCA\) 的深度。所以我们把 \([l,r]\) 之间的点到根节点路径上各加一,再查询 \(z\) 到根节点的路径的值之和即为 \(\sum_{i=l}^{r}\text{dep}[\text{LCA}(i,z)]\) 。显然这个问题(路劲加,路劲查询)可以用树剖求。

但是 \(l,r\) 不固定,我们可以离线用前缀和思想做,\(\sum_{i=l}^{r}\text{dep}[\text{LCA}(i,z)]=\sum_{i=1}^{r}\text{dep}[\text{LCA}(i,z)]-\sum_{i=1}^{l-1}\text{dep}[\text{LCA}(i,z)]\) 。
把问题排序,然后离线做就好了。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10;
int read(){
	int x=0,f=1;char c=getchar();
	while(c>'9' || c<'0'){if(c=='-')f=-1;c=getchar();}
	while(c>='0' && c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return x*f;
}
int n,m;
struct Seg{
	int lzy[N<<2],val[N<<2],len[N<<2];
	void build(int u,int l,int r){
		len[u]=r-l+1;
		if(l==r)return;int mid=(l+r)>>1;
		build(u<<1,l,mid);build(u<<1|1,mid+1,r);
		return;
	}
	void pushdown(int u){
		if(lzy[u]){
			val[u<<1]+=lzy[u]*len[u<<1];
			val[u<<1|1]+=lzy[u]*len[u<<1|1];
			lzy[u<<1]+=lzy[u];lzy[u<<1|1]+=lzy[u];
			lzy[u]=0;
		}
		return;
	}
	void pushup(int u){val[u]=val[u<<1]+val[u<<1|1];return;}
	void update(int u,int l,int r,int L,int R){
		if(L<=l && r<=R){val[u]+=len[u];lzy[u]++;return;}
		pushdown(u);int mid=(l+r)>>1;
		if(L<=mid)update(u<<1,l,mid,L,R);
		if(R>mid)update(u<<1|1,mid+1,r,L,R);
		pushup(u);return;
	}
	int query(int u,int l,int r,int L,int R){
		if(L<=l && r<=R)return val[u];
		pushdown(u);int mid=(l+r)>>1,res=0;
		if(L<=mid)res+=query(u<<1,l,mid,L,R);
		if(R>mid)res+=query(u<<1|1,mid+1,r,L,R);
		return res;
	}
}E;
struct Tree{
	int head[N],to[N<<1],last[N<<1],tot;
	void add(int u,int v){to[++tot]=v,last[tot]=head[u],head[u]=tot;return;}
	int maxson[N],dep[N],top[N],sze[N],cnt,dfn[N],fa[N];
	void dfs1(int u,int d){
		dep[u]=d;sze[u]=1;
		for(int i=head[u];i;i=last[i]){
			int v=to[i];dfs1(v,d+1);
			sze[u]+=sze[v];
			if(sze[v]>sze[maxson[u]])maxson[u]=v;
		}
		return;
	}
	void dfs2(int u,int t){
		top[u]=t;dfn[u]=++cnt;
		if(maxson[u])dfs2(maxson[u],t);
		for(int i=head[u];i;i=last[i]){
			int v=to[i];if(v!=maxson[u])dfs2(v,v);
		}
	}
	void update(int x){
		while(x!=0){E.update(1,1,n,dfn[top[x]],dfn[x]);x=fa[top[x]];}
		return;
	}
	int query(int x){
		int res=0;
		while(x!=0){res+=E.query(1,1,n,dfn[top[x]],dfn[x]);x=fa[top[x]];}
		return res;
	}
}T;
struct Q{
	int tim,id,z,kd;
	bool operator<(const Q A)const{return tim<A.tim;} 
}q[N<<1];
int ans[N];
int main(){
	n=read(),m=read();E.build(1,1,n);
	for(int i=2;i<=n;i++){T.fa[i]=read()+1;T.add(T.fa[i],i);}
	T.dfs1(1,1);T.dfs2(1,1);
	for(int i=1;i<=m;i++){
		int l=read()+1,r=read()+1,z=read()+1;
		q[2*i-1].id=q[2*i].id=i;
		q[2*i-1].tim=l-1,q[2*i-1].z=z,q[2*i-1].kd=-1;
		q[2*i].tim=r,q[2*i].z=z,q[2*i].kd=1;
	}
	sort(q+1,q+2*m+1);int tim=0;
	for(int i=1;i<=2*m;i++){
		while(tim<q[i].tim){tim++;T.update(tim);}
		ans[q[i].id]+=q[i].kd*T.query(q[i].z);
	}
	for(int i=1;i<=m;i++)printf("%d\n",ans[i]%201314);
	return 0;
}

标签:int,text,LNOI2014,maxson,dfn,P4211,res,LCA
From: https://www.cnblogs.com/FJOI/p/17368882.html

相关文章

  • LCA(最近公共祖先)学习笔记
    前言没想到干完lca的时间比tarjan的还要长(我不能这么弱下去了!!)前置知识dfs序这东西有点类似于时间戳(dfn),但是它分为两部分(回溯之前和回溯之后)。并且dfs序还分为两种。这里只介绍一倍的dfs序。如上图,蓝色代表左端点,红色代表右端点,(学过Tarjan的都知道),蓝色其实就是这棵树的dfn(......
  • LeetCode 周赛 341 场,模拟 / 树上差分 / Tarjan 离线 LCA / DFS
    本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]提问。大家好,我是小彭。上周末有单双周赛,双周赛我们讲过了,单周赛那天早上有事没参加,后面做了虚拟竞赛,然后整个人就不好了。前3题非常简单,但第4题有点东西啊,差点就放弃了。最后,被折磨了一个下午和一个大夜......
  • LCA——ST表+欧拉序
    了解到一个quan新的东西:用ST表(欧拉序)实现LCA(树上最近公共祖先)欧拉序前序遍历得到的序列,叫dfs序但数字可以重复出现,一进一出,叫欧拉序会发现根结点总在中间而根结点是该段序列深度最小的点因此两个点的LCA,就是在该序列上两个点第一次出现的区间内深度最小的那个点即转......
  • Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not b
    最近在使用图片导出base64的时候遇到下面的报错我的代码如下letmyImage=newImage();myImage.src=imgSrcData;myImage.crossOrigin='Anonymous';网上查阅资料,都说给图片设置 crossOrigin值为 Anonymous就可以了,我这么设置,但是依然不行,后来才发现,设置这个crossO......
  • vue pc使用htmlCanvas Jspdf 实现点击将页面生成图片并转成pdf下载
    <template><divid="main"ref="workbench"v-loading="loading"class="echartsPdf">需要的内容</div></template><script>importhtml2canvasfrom'html2canvas'importJspdf......
  • 20230410 训练记录:最小瓶颈路 / lca
    初识最小瓶颈路其实是上海那道著名的铜牌题,其次就是P1396营救。P1967[NOIP2013提高组]货车运输/最小瓶颈路https://www.luogu.com.cn/problem/P1967\(\mathcalO(m\logm+(n+q)\logn)\)最大生成树(森林)两点间最小边权,直接在倍增lca向上爬的时候更新答案。问......
  • Socialcam引进YouTube内容 自砸招牌还是另有所图
    你能想象优酷视频网站上充斥着腾讯视频内容吗?这种事情就发生在知名个人视频分享应用Socialcam上,近来这个应用频频出现YouTube网站内容,而且YouTube标识赫然在目。详情:这对于一个在排行榜上到了一定位置,用户群开始稳定的应用来说,着实令人费解。前些日子苹果AppStore还显示了Social......
  • [LNOI2014] LCA 树链剖分+离线处理+lca转化
    困困的开始了我的修炼树剖之旅途考虑怎么搞这个lca是说,习惯了倍增求lca,突然冒出这么一个东西还真不会搞那要么能一次性求很多个lca(?),要么把deep[lca(i,z)]这个东西转化......
  • 欧拉序+ST表 O(nlogn+q)求LCA
    欧拉序:每次遍历到树上的一个点,就加进欧拉序如123​45这颗树的欧拉序是121343431这样我们可以发现一个重要的性质:两个点的LCA是欧拉序之间dep最小的点......
  • 最近树上公共祖先(LCA)
    捏......