首页 > 其他分享 >HT-014 Div3 跳棋 题解 [ 黄 ] [ 并查集 ] [ 树型结构 ]

HT-014 Div3 跳棋 题解 [ 黄 ] [ 并查集 ] [ 树型结构 ]

时间:2024-07-06 16:52:13浏览次数:10  
标签:200005 int 题解 可以 查集 jp HT 跳棋

分析

依旧是一个连通块题。

观察题面不难发现两个重要性质:

  1. 一个跳棋只能以它旁边的两个跳棋为中点跳跃,且满足跳跃路线中 除中点以外没有其它跳棋阻挡。
  2. 只有我们的跳棋可以移动。
  3. 跳棋的操作具有可逆性/对称性。

第三条性质可以这么理解,就是一个跳棋跳过去之后,它还可以跳回来。
因此,无论我们从左右两边的哪一边开始起跳,都可以跳出最佳路径。

于是我们规定跳棋只能向右跳。(你规定向左跳也可以)

然后发现,跳棋跳的路线,是可以抽象成一棵树的。
每次从 \(u\) 点跳向 \(v\) 点,可以看作 \(v\) 为父亲节点,\(u\) 为儿子节点,两者连一条边。
这样树就建好了。

但这样仍然会超时,因为每次我们从树的叶子节点进入,进行查询操作,每个格子进行一遍,就相当于是 \(O(n^2)\) 的复杂度了。

并且还有一个性质,就是我们只注重跳到的最后的结果。
所以我们想到既可以实现 \(O(1)\) 快速查询,又可以维护儿子与祖先关系的并查集
简化树的操作,便是路径压缩

由于是连通块,所以使用 BFS 看似也可以实现,但我没试过,并且感觉有点难写。或者写遍历树的做法也可以,稍微比 BFS 好写些。实现的好那么上面三种做法都没问题。

时间为 \(O(n)\) 。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,f[200005],l[200005],r[200005],jp[200005],fr[200005],ans=0;
bool blk[200005];
void init()
{
	for(int i=0;i<200005;i++)
	{
		f[i]=i;
		l[i]=i;
		r[i]=i;
	}
}
int findf(int x)
{
	if(f[x]!=x)f[x]=findf(f[x]);
	return f[x];
}
void combine(int x,int y)
{
	int fx=findf(x),fy=findf(y);
	f[fx]=fy;
	l[fy]=min(l[fy],l[fx]);
	r[fy]=max(r[fy],r[fx]);
}
int main()
{
	freopen("jump.in","r",stdin);
	freopen("jump.out","w",stdout);
	cin>>n>>m;
	init();
	for(int i=1;i<=m;i++)
	{
		int a;
		cin>>a;
		blk[a]=1;
	}
	for(int i=1;i<=n;i++)
	{
		fr[i]=fr[i-1];
		fr[i]+=blk[i];
	}
	for(int i=n,b=0x3f3f3f3f;i>=1;i--)
	{
		if(blk[i])
		{
			jp[i]=0x3f3f3f3f;
			b=i;
			continue;
		}
		jp[i]=b;
	}
	for(int i=1;i<=n;i++)
	{
		if(jp[i]>=0x3f3f3f3f)continue;
		int p=2*jp[i]-i;
		if(p>i&&p<=n&&(fr[p]-fr[i-1])==1)combine(i,p);
	}
	for(int i=1;i<=n;i++)
	{
		int fi=findf(i);
		ans=max(ans,abs(r[fi]-l[fi]));
	}
	cout<<ans;
	return 0;
}

标签:200005,int,题解,可以,查集,jp,HT,跳棋
From: https://www.cnblogs.com/zhr0102/p/18287458

相关文章

  • httpie/xh 与 curl 对比
    xh相当于是rust版的httpie(httpie是python写的)安装xhhttps://github.com/ducaale/xh?tab=readme-ov-file#via-a-package-managercargoinstallxh--lockededGETcurlhttps://httpbin.org/get?hello=worldxhhttpbin.org/gethello==world#xh默认请求httpx......
  • [POI2015] WYC 题解
    [POI2015]WYC显然矩阵乘法发现点数和边权非常小,所以可以考虑拆点把每个点拆为\(u_1\),\(u_2\),\(u_3\),初始:\(u_1\tou_2\),\(u_2\tou_3\),每一条加边:\(u+(w-1)\timesn\tov\)因为\(k\)非常大,所以考虑倍增优化注意:答案会爆longlong,需要使用unsignedlonglong//Pro......
  • 01 Web基础与HTTP协议
    1.1Web基础本章将介绍Web基础知识,包括域名的概念、DNS原理、静态网页和动态网页的相关知识。1.1.1.域名概述1.域名的概念ip地址不易记忆2.早期使用host文件解析域名主机名重复主机维护困难3.DNS分布式层次式4.域名空间结构根域顶级域组织域国家域二级域名FQDN......
  • python-docx库 写入docx时中文不适配问题,中文异常问题解决办法。
    python-docx库写入docx时中文不适配问题,中文异常问题解决办法。通过以下方法可以成功将正文修改为宋体字体。这个是全文设置。fromdocx.oxml.nsimportqndoc=Document()doc.styles['Normal'].font.name=u'宋体'doc.styles['Normal']._element.rPr.rFonts.set(qn('w:......
  • HashTable,ArrayList,queue等常用方法
    HashTable,ArrayList,queue等常用方法HashMap是Java中非常常用的集合类,它存储键值对,并提供了一系列方便的方法来操作这些数据。以下是一些HashMap的常用方法:1.添加和获取元素:put(key,value):将指定的键值对添加到HashMap中。如果键已存在,则更新对应的值。get(ke......
  • ZeroMQ最全面试题解读(3万字长文)
    目录解释ZeroMQ是什么,它的主要用途是什么?ZeroMQ支持哪些通信模式?描述一下ZeroMQ中的“消息”和“消息帧”如何在C++中初始化一个ZeroMQ上下文?在ZeroMQ中,如何创建一个套接字并将其绑定到特定端口?解释什么是“管道模式”(PipePattern)说明如何使用ZeroMQ进行点对点通信Zer......
  • html+css随手记录第二天
    1.CSS简介    需要对下面的知识有基本的了解:HTML/XHTML1.1什么是CSS?    CSS指层叠样式表(CascadingStyleSheets)    css样式定义如何显示HTML元素,样式通常存储在样式表中,把样式添加到HTML4.0中,是为了解决内容与表现分离的问题,外部样......
  • 题解:CF1256D Binary String Minimizing
    贪心。数据范围\(n\le10^{6}\),因此我们要用时间复杂度为\(\mathcal{O}\left(n\right)\)的算法来解决这个问题。思路从左至右扫一遍序列,如果遇到\(10\),则要将这个\(0\)交换到前面的位置。由于是字典序最小,\(0\)应该尽量在最高位。现在需要知道这个\(0\)被交换到哪......
  • HTML 【实用教程】(2024最新版)
    核心思想——语义化【面试题】如何理解HTML语义化?仅通过标签便能判断内容的类型,特别是区分标题、段落、图片和表格增加代码可读性,让人更容易读懂对SEO更加友好,让搜索引擎更容易读懂html文件的基本结构html文件的文件后缀为.html,如index.htmlvscode中......
  • HTML【详解】超链接 a 标签的四大功能(页面跳转、页内滚动【锚点】、页面刷新、文件下
    超链接a标签主要有以下功能:跳转到其他页面<ahref="https://www.baidu.com/"target="_blank">百度</a>href:目标页面的url地址或同网站的其他页面地址,如detail.htmltarget:打开目标页面的方式_self:在同一个网页中显示(默认值)_blank:在新的窗口中打开【常用】_......