HT-014 Div3 跳棋 题解 [ 黄 ] [ 并查集 ] [ 链表 ]
分析
依旧是一个连通块题。
观察题面不难发现两个重要性质:
- 一个跳棋只能以它旁边的两个跳棋为中点跳跃,且满足跳跃路线中 除中点以外没有其它跳棋阻挡。
- 只有我们的跳棋可以移动。
- 跳棋的操作具有可逆性/对称性。
第三条性质可以这么理解,就是一个跳棋跳过去之后,它还可以跳回来。
因此,无论我们从左右两边的哪一边开始起跳,都可以跳出最佳路径。
于是我们规定跳棋只能向右跳。(你规定向左跳也可以)
然后发现,跳棋跳的路线,是可以抽象成一条链的。
每次从 \(u\) 点跳向 \(v\) 点,可以看作两者连一条边。
这样链就建好了。
但这样仍然会超时,因为每次我们从链的某个节点进入,走到最后进行查询操作,每个格子进行一遍,就相当于是 \(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;
}
HT-014 Div3 跳棋 题解 [ 黄 ] [ 并查集 ] [ 链表 ]的更多相关文章
- Codeforces #541 (Div2) - F. Asya And Kittens(并查集+链表)
Problem Codeforces #541 (Div2) - F. Asya And Kittens Time Limit: 2000 mSec Problem Description Inp ...
- 【HNOI2012】永无乡 题解(并查集+线段树合并)
题目链接 给定一张含$n$个点$m$条边的无向图,每个点有一个重要指数$a_i$.有两种操作:1.在$x$和$y$之间连一条边:2.求$x$所在连通块中重要程度第$k$小的点. ----------- ...
- 【CF878C】Tournament set+并查集+链表
[CF878C]Tournament 题意:有k个项目,n个运动员,第i个运动员的第j个项目的能力值为aij.一场比赛可以通过如下方式进行: 每次选出2个人和一个项目,该项目能力值高者获胜,败者被淘汰 ...
- CodeForces 566D Restructuring Company (并查集+链表)
题意:给定 3 种操作, 第一种 1 u v 把 u 和 v 合并 第二种 2 l r 把 l - r 这一段区间合并 第三种 3 u v 判断 u 和 v 是不是在同一集合中. 析:很容易知道是用并 ...
- luoguP1525 关押罪犯 题解(NOIP2010)(并查集反集)
P1525 关押罪犯 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include<c ...
- 100: cf 878C set+并查集+链表
$des$Berland要举行 $n$ 次锦标赛,第一次只有一个人,之后每一次会新加入一个人.锦标赛中有 $k$ 种运动项目,每个人在这 $k$ 种项目上都有一个能力值,每次会选择任意两个还未被淘汰的 ...
- CF469D Two Set (并查集)
Codeforces Round #268 (Div. 2)D Codeforces Round #268 (Div. 1)B CF468B D. Two Sets time limit per te ...
- CF455C Civilization (并查集)
CF456E Codeforces Round #260 (Div. 1) C Codeforces Round #260 (Div. 2) E http://codeforces.com/conte ...
- Educational Codeforces Round 7 C. Not Equal on a Segment 并查集
C. Not Equal on a Segment 题目连接: http://www.codeforces.com/contest/622/problem/C Description You are ...
- Codeforces Round #260 (Div. 1) C. Civilization 并查集,直径
C. Civilization Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/455/probl ...
随机推荐
- golang之命令行参数
当我们希望通过命令行启动Golang程序,获取输入的各种形式参数时,该如何处理呢? [os.Args] os.Args是一个string的切片,用来存储所有的命令行参数,包括go run main.g ...
- CudaSPONGE高性能GPU分子模拟
技术背景 CudaSPONGE是基于CUDA C开发的一款纯GPU分子动力学模拟软件,具有模块化和高性能的特点.官方基本介绍内容如下: 分子动力学(Molecular Dynamics, MD)模拟是 ...
- docker构建supervisor镜像
1 介绍 记录使用docker 构建包含 supervior 的镜像, supervisor: 是一个管理和监控进程的程序,可以方便的通过配置文件来管理我们的任务脚本 将supervisor构建到系统 ...
- ES6 面试题
新增了哪些属性? 新增块级作用域:let.const 新增数据类型:Symbol 表示独一无二的值 新增数据结构: Set,类似数组,所有数据是唯一的: Map,键值对的结合,传统的 Object 只 ...
- R数据分析:做量性研究的必备“家伙什”-furniture包介绍
In conjunction with many other tidy tools, the package should be useful for health, behavioral, and ...
- 中电金信成为开源风险评估与治理技术实验室软件物料清单(SBOM)工作组成员单位
近期,中电金信成功加入国家工业信息安全发展研究中心开源风险评估与治理技术实验室软件物料清单(SBOM)工作组,成为其成员单位,并同步加入"筑链计划"之中. SBOM是Softwar ...
- APIView执行流程(源码分析)、Request对象源码分析
目录 一.APIView执行流程--源码分析(难,了解) 1.1 基于APIView+JsonResponse编写接口 1.2 基于APIView+Response 写接口 1.3 APIView的执 ...
- arch linux deepin-wine-wechat
https://aur.archlinux.org/packages/deepin-wine-wechat md5sum for WeChatSetup-3.9.0.28.exe should be ...
- Visual Studio - API调试与测试工具之HTTP文件
后端开发,我们对于Api接口调试测试大致有以下方法:单元测试.Swagger.Postman. 但是每种方式也都有其局限性,几年前使用Visual Studio Code开发过一段时间,接触了REST ...
- Tesseract开源的OCR工具及python pytesseract安装使用
一 .介绍 Tesseract是一款由Google赞助的开源OCR. pytesseract是python包装器,它为可执行文件提供了pythonic API. Tesseract 已经有 30 年历 ...