首页 > 其他分享 >luoguP3533 lca

luoguP3533 lca

时间:2024-07-13 22:42:12浏览次数:9  
标签:chamber luoguP3533 should int lca now their

[POI2012] RAN-Rendezvous

题目描述

Byteasar is a ranger who works in the Arrow Cave - a famous rendezvous destination among lovers.

The cave consists of \(n\) chambers connected with one-way corridors.

In each chamber exactly one outgoing corridor is marked with an arrow.

Every corridor leads directly to some (not necessarily different) chamber.

The enamoured couples that agree to meet in the Arrow Cave are notorious for forgetting to agree upon specific chamber, and consequently often cannot find their dates.

In the past this led to many mix-ups and misunderstandings\dots But ever since each chamber is equipped with an emergency telephone line to the ranger on duty, helping the enamoured find their dates has become the rangers' main occupation.

The rangers came up with the following method.

Knowing where the enamoured are, they tell each of them how many times they should follow the corridor marked with an arrow in order to meet their date.

The lovers obviously want to meet as soon as possible - after all, they came to the cave to spend time together, not to wander around alone!

Most rangers are happy to oblige: they do their best to give each couple a valid pair of numbers such that their maximum is minimal.

But some rangers, among their numbers Byteasar, grew tired of this extracurricular activity and ensuing puzzles. Byteasar has asked you to write a program that will ease the process. The program, given a description of the cave and the current location of \(k\) couples, should determine \(k\) pairs of numbers \(x_i\) and \(y_i\) such that if the \(i\)-th couple follows respectively: he \(x_i\) and she \(y_i\) corridors marked with arrows,then they will meet in a single chamber of the cave \(max(x_i,y_i)\) is minimal,subject to above \(min(x_i,y_i)\) is minimal,if above conditions do not determine a unique solution, then the woman should cover smaller distance (\(x_i\ge y_i\)).

It may happen that such numbers \(x_i\) and \(y_i\) do not exist - then let \(x_i=y_i=-1\). Note that it is fine for several couples to meet in a single chamber. Once the lovers have found their dates, they will be happy to lose themselves in the cave again...

给定一棵内向森林,多次给定两个点a和b,求点对(x,y)满足:

1.从a出发走x步和从b出发走y步会到达同一个点

2.在1的基础上如果有多解,那么要求max(x,y)最小

3.在1和2的基础上如果有多解,那么要求min(x,y)最小

4.如果在1、2、3的基础上仍有多解,那么要求x>=y

输入格式

In the first line of the standard input there are two positive integers \(n\) and \(k\)(\(1\le n,k\le 500\ 000\)), separated by a single space, that denote the number of chambers in the Arrow Cave and the number of couples who want to find their dates, respectively.

The chambers are numbered from 1 to \(n\), while the enamoured couples are numbered from 1 to \(k\).

The second line of input contains \(n\) positive integers separated by single spaces:

the \(i\)-th such integer determines the number of chamber to which the corridor marked with an arrow going out of chamber \(i\) leads.

The following \(k\) lines specify the queries by the separated couples. Each such query consists of two positive integers separated by a single space - these denote the numbers of chambers where the lovers are - first him, then her.

In the tests worth 40% of the total points it additionally holds that \(n,k\le 2\ 000\).

输出格式

Your program should print exactly \(k\) lines to the standard output, one line per each couple specified in the input:

the \(i\)-th line of the output should give the instructions for the \(i\)-th couple on the input.

I.e., the \(i\)-th line of output should contain the integers \(x_i,y_i\), separated by a single space.

样例 #1

样例输入 #1

12 5
4 3 5 5 1 1 12 12 9 9 7 1
7 2
8 11
1 2
9 10
10 5

样例输出 #1

2 3
1 2
2 2
0 1
-1 -1

提示

给定一棵内向基环森林,多次给定两个点a和b,求点对(x,y)满足:

1.从a出发走x步和从b出发走y步会到达同一个点

2.在1的基础上如果有多解,那么要求max(x,y)最小

3.在1和2的基础上如果有多解,那么要求min(x,y)最小

4.如果在1、2、3的基础上仍有多解,那么要求x>=y

看看样例,其实就能发现,这是一个内向基环树森林,基环树森林。。自环也算环哦。。。

对于基环树,其实直接缩点,森林也是很好处理。但是问题在于是5e5个询问,同时还需要处理多解的情况。
先考虑怎么求出一个解吧

其实只需要管\(x-y\)的值即可(x-y指步数之差的绝对值),先求出lca,如果他们的lca是经过缩短的基环,由于是单向边的原因,依旧是一个确定的解,除非是围绕着这个环再转一圈。多解的情况感觉非常少,因为是单向树的原因,找到lca后,这两个点只能一起走动,而如果他们之间的距离差减去lca产生的距离差不为零,那么只能通过绕环走一圈来消除。也就是这个距离差减去lca产生的距离差,这个值如果不是环的长度的整数倍,那么就是确定无解。

哦,看错题了。拿这题没了啊,直接缩点,求lca,要么无解,要么lca不在基环上,要么lca在基环上。其中第一个情况,是很好判断的。直接看看是否在同一棵树上,第二个,这个点对就是两个点到lca的距离,看看要求,\(max(x,y)\)最小,如果向上继续的话,两个都变大。
而第三个情况,其实也是,直接让走到基环上后,小的步数走到另一个点的位置即可。后面的条件是不是有点多余?
不知道啊。先写吧

写到屎了

250行,70tps,实在找不到错了,写了一天了。
不管了,反正该学的学到了

就这样吧

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
	int a=0,b=1;char c=getchar();
	for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
	for(;c>='0'&&c<='9';c=getchar())a=a*10+c-'0';
	return a*b;
}
struct edge
{
	int next,to;
}e1[500001],e2[1000001];
int head1[500001],head2[1000001],tot1,tot2,n,k;
inline void add1(int i,int j)
{
	e1[++tot1].next=head1[i];
	e1[tot1].to=j;
	head1[i]=tot1;
}
inline void add2(int i,int j)
{
	e2[++tot2].next=head2[i];
	e2[tot2].to=j;
	head2[i]=tot2;
}
bool vis[500001];int deg[500001],a[500001];
queue<int> q;
void topo()
{
	for(int i=1;i<=n;i++)
	{
		if(deg[i]==0)q.push(i);
	}
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		for(int i=head1[x];i!=0;i=e1[i].next)
		{
			int u=e1[i].to;
//			if(deg[u]==0)continue;
			deg[u]--;
			if(deg[u]==0)
			{
				q.push(u);
			}
		}
	}
}
vector<int> rmap[500001];
map<int,int> ma;
int bcj[500001][2];
int Get_fa(int x,int k)
{
	if(bcj[x][k]==x)return x;
	return bcj[x][k]=Get_fa(bcj[x][k],k);
}
int cnt=0;
vector<int> root;
void tarjan_awa(int st)
{
	q.push(st);
	root.push_back(++cnt);
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		if(!deg[x])continue;
		if(vis[x])continue;
		vis[x]=1;
		rmap[cnt].push_back(x);
		ma[x]=cnt;
		for(int i=head1[x];i!=0;i=e1[i].next)
		{
			int u=e1[i].to;
			if(!deg[u])continue;
			q.push(u);
		}
	}
}
int dep[500001][21],f[500001][21];
int num[500001];
void dfs(int x,int fa,int now)
{
	vis[x]=1;
//	cout << x <<endl;
	dep[x][0]=now-1;f[x][0]=fa;
	for(int i=head2[x];i!=0;i=e2[i].next)
	{
		int u=e2[i].to;
		if(vis[u])continue;
		if(u==fa)continue;
		dfs(u,x,now+1);
	}
}
int ask_lca(int x,int y)
{
	if(dep[x][0]<dep[y][0])swap(x,y);
	int now=19;
	while(now>=0)
	{
		if(dep[x][now]>dep[y][0])x=f[x][now];
		now--;
	}
	now=19;
	if(x==y)return x;
	while(now>=0)
	{
		if(f[x][now]!=f[y][now])y=f[y][now],x=f[x][now];
		now--;
	}
	return f[x][0];
	//mty dzs¿ìȥдÌâ ËäÈ»ÎÒ²ÂÄã¿´²»µ½ 
}
void Get_sequence(int x,int fa,int now)
{
	num[x]=++now;
	for(int i=head1[x];i!=0;i=e1[i].next)
	{
		int u=e1[i].to;
		if(deg[u]==0||num[u]!=0)continue;
		Get_sequence(u,x,now);
	}
}
int main()
{
	n=read();k=read();
	for(int i=1;i<=n;i++)bcj[i][0]=bcj[i][1]=i;
	for(int i=1;i<=n;i++)
	{
		int x=read();a[i]=x;
		add1(i,x);deg[x]++;
		bcj[i][0]=Get_fa(x,0);
	}
	topo();
	for(int i=1;i<=n;i++)
	{
		if(deg[i]==0)bcj[i][1]=Get_fa(a[i],1);
	}
//	for(int i=1;i<=n;i++)
//	{
//		cout<<Get_fa(i,1)<<' ';
//	}
//	cout<<endl;
	for(int i=1;i<=n;i++)
	{
		if(deg[i]!=0&&num[i]==0)
		{
			Get_sequence(i,0,0);
		}
	}
	for(int i=1;i<=n;i++)//Ëõµã 
	{
		if(deg[i]==0&&vis[i]==0)
		{
			vis[i]=1;
			rmap[++cnt].push_back(i);
			ma[i]=cnt;
		}
		else
		if(deg[i]!=0&&vis[i]==0)
		{
			tarjan_awa(i);
		}
	}
//	for(int i=1;i<=n;i++)
//	{
//		cout<<ma[i]<<' ';
//	}
//	cout<<endl;
	for(int i=1;i<=n;i++)
	{
		add2(ma[i],ma[a[i]]);
		add2(ma[a[i]],ma[i]);
	}
	memset(vis,0,sizeof(vis));
	for(int i=0;i<root.size();i++)
	{
//		cout<<"?"<<endl;
		dfs(root[i],0,1);
//		cout<<root[i]<<' ';
	}
//	cout<<endl;
	memset(vis,0,sizeof(vis));
	for(int i=0;i<=18;i++)
	{
		for(int j=1;j<=cnt;j++)
		{
			dep[j][i+1]=dep[f[j][i]][i];
			f[j][i+1]=f[f[j][i]][i];
		}
	}
//	for(int i=1;i<=cnt;i++)
//	{
//		cout<<dep[i][0]<<' '<<f[i][0]<<endl;
//	}
	for(int i=1;i<=k;i++)
	{
		int x=read(),y=read();int rx=x,ry=y;
		if(Get_fa(x,0)!=Get_fa(y,0))
		{
			cout<<-1<<' '<<-1<<endl;
			continue;
		}
		x=ma[x],y=ma[y];
		int lca=ask_lca(x,y);
		if(rmap[lca].size()==1)
		{
			cout<<dep[x][0]-dep[lca][0]<<' '<<dep[y][0]-dep[lca][0]<<endl;
			continue;
		}
//		cout<<lca<<endl;
		int st1=Get_fa(rx,1),st2=Get_fa(ry,1);
		st1=num[st1],st2=num[st2];
		int movex,movey;
//		cout<<st1<<' '<<st2<<endl;
		if(st1==st2)movex=movey=0;
		if(st1>st2)
		{
			movex=rmap[ma[Get_fa(rx,1)]].size()-st1+st2;
			movey=st1-st2; 
		}
		else
		if(st1<st2)
		{
			movex=st2-st1;
			movey=rmap[ma[Get_fa(rx,1)]].size()-st2+st1;
		}
//		cout<<dep[x][0]<<' '<<dep[y][0]<<' '<<movex<<' '<<movey<<endl;
		int len1=dep[x][0],len2=dep[y][0];
//		cout<<len1<<' '<<len2<<endl;
//		if(max(len1+movex,len2)!=max(len2+movey,len1))
//		{
			if(max(len1+movex,len2)<=max(len2+movey,len1))
			{
				cout<<len1+movex<<' '<<len2<<endl;
			}
			else
			{
				cout<<len1<<' '<<len2+movey<<endl;
			}
//		}
//		else
//		{
//			cout<<len1+movex<<' '<<len2<<endl;
//		}
	}
	return 0;
}
/*


1 4
2 3
3 5
4 5
5 1
6 1
7 12
8 12
9 9
10 9
11 7
12 1

*/

标签:chamber,luoguP3533,should,int,lca,now,their
From: https://www.cnblogs.com/HLZZPawa/p/18300854

相关文章

  • 从 dfs 序求 lca 到虚树到树分块 学习笔记
    前言想象我在口胡三样我都不熟悉的东西并尝试称之为“学习笔记”。其实不过是我自己对于它的一点小理解,甚至可能是错误的!无所谓,口胡!口胡!口胡!口胡!口胡!一些备注\(dfn_u\)为点\(u\)的dfn序,\(nfd_i\)表示第\(i\)个dfs到的点是啥(前者的反数组)dfs序求lca这个很简单,想......
  • 基于OpenLCA、GREET、R语言的生命周期评价方法、模型构建
    生命周期分析(LifeCycleAnalysis,LCA)是评价一个产品系统生命周期整个阶段——从原材料的提取和加工,到产品生产、包装、市场营销、使用、再使用和产品维护,直至再循环和最终废物处置——的环境影响的工具。这种方法被认为是一种“从摇篮到坟墓”的方法。生命周期分析是一......
  • 【YOLOv8改进】MLCA(Mixed local channel attention):混合局部通道注意力(论文笔记+引
    摘要本项目介绍了一种轻量级的MixedLocalChannelAttention(MLCA)模块,该模块同时考虑通道信息和空间信息,并结合局部信息和全局信息以提高网络的表达效果。基于该模块,我们提出了MobileNet-Attention-YOLO(MAY)算法,用于比较各种注意力模块的性能。在PascalVOC和SMID数......
  • 【YOLOv8改进】MLCA(Mixed local channel attention):混合局部通道注意力(论文笔记+引
    摘要本项目介绍了一种轻量级的MixedLocalChannelAttention(MLCA)模块,该模块同时考虑通道信息和空间信息,并结合局部信息和全局信息以提高网络的表达效果。基于该模块,我们提出了MobileNet-Attention-YOLO(MAY)算法,用于比较各种注意力模块的性能。在PascalVOC和SMID数......
  • 【YOLOv10改进[注意力]】在YOLOv10中使用注意力MLCA的实践+ 含全部代码和详细修改方式
    本文将进行在YOLOv10中添加注意力MLCA的实践,助力YOLOv10目标检测效果的实践,文中含全部代码、详细修改方式以及手撕结构图。助您轻松理解改进的方法。改进前和改进后的参数对比: 目录一MLCA二在YOLOv10中使用注意力MLCA的实践1整体修改......
  • 【YOLOv8改进[注意力]】在YOLOv8中添加MLCA混合局部通道注意力的实践 + 含全部代码和
    本文将进行在YOLOv8中添加MLCA混合局部通道注意力的实践,助力YOLOv8目标检测效果的实践,文中含全部代码、详细修改方式以及手撕结构图。助您轻松理解改进的方法。改进前和改进后的参数对比:目录一MLCA二在YOLOv8中添加MLCA注意力1整体修改2......
  • [YOLOv10涨点改进:注意力魔改 | 轻量级的 Mixed Local Channel Attention (MLCA),加强通
    本文属于原创独家改进:一种轻量级的MixedLocalChannelAttention(MLCA)模块,该模块考虑通道信息和空间信息,并结合局部信息和全局信息以提高网络的表达效果1.YOLOv10介绍论文:[https://arxiv.org/pdf/2405.14458]代码:https://gitcode.com/THU-MIG/yolov10?utm_source=c......
  • 使用自定义查询参数获取 fullcalendar api
    我正试图配置fullcalendar5从数据库中获取api。除了开始和结束之外,我还想向请求传递额外的查询参数。我已经尝试过这种方法,但发现请求总是忽略附加参数。events:{url:'http://localhost:4000/api/timesheet'、type:'GET'、......
  • Webphser Applcation Server Dmgr无法正常启动
    好久不来园子,也好久没处理过WAS问题了,今天客户想部署应用,发现Dmgr无法访问,去重启,无法正常启动。直接上日志:[24-6-123:00:55:025CST]00000009MultiScopeRecA  CWRLS0008E:正在将恢复日志标记为“失败”。[1transaction][24-6-123:00:55:026CST]00000009MultiScope......
  • PEnum_DistributionSystemElectricalCategory
    PEnum_DistributionSystemElectricalCategory  TypevaluesTypeDescriptionEXTRALOWVOLTAGENodescriptionavailable.HIGHVOLTAGENodescriptionavailable.LOWVOLTAGENodescriptionavailable.OTHERrequiredcategorynotonscaleNOTKN......