题目链接:link

题意已经挺简易了,直接上思路吧。

我们设 \(f_{i,j}\) 表示当前在第 \(i\) 个时刻,一个棋子在 \(x_i\) 位置,另一个棋子在 \(j\) 位置的最小代价之和。

状态转移有两种:

\[f_{i,j}+|x_i-x-i+1|\rightarrow f_{i+1,j}
\]
\[f_{i,j}+|j-x_i+1|\rightarrow f_{i+1,x_i+1}
\]

我们可以使用线段树来维护 \(f_{i,\cdots}\),考虑每次从 \(f_{i,\cdots}\rightarrow f_{i+1,\cdots}\) 可以发现只需要做一个全局加和单点修改,同时还要维护 \(f_{i,j}+|j-x_i+1|\) 的最小值,这个拆开绝对值之后只需要算两段区间的 \(f_{i,j}+j,f_{i,j}-j\) 的最小值,这些都可以用线段树维护,这个算法的复杂度就是 \(\mathcal{O(n+Q\log n)}\)。

上代码:

#include<bits/stdc++.h>
#define I using
#define AK namespace
#define IOI std
#define i_ak return
#define ioi 0
#define i_will signed
#define ak main
#define IMO ()
#define int long long
#define p1 (p<<1)
#define p2 ((p<<1)|1)
I AK IOI;
int n,q,A,B,a[200010],d[2][800010],b[800010];
void cl(int p){
if(b[p]){
b[p1]+=b[p];
b[p2]+=b[p];
d[0][p1]+=b[p];
d[1][p1]+=b[p];
d[0][p2]+=b[p];
d[1][p2]+=b[p];
b[p]=0;
}
}
void build(int s,int t,int p){
if(s==t){
d[0][p]=min(abs(a[1]-A)+abs(s-B),abs(a[1]-B)+abs(s-A))-s;
d[1][p]=min(abs(a[1]-A)+abs(s-B),abs(a[1]-B)+abs(s-A))+s;
return;
}
int mid=s+t>>1;
build(s,mid,p1);
build(mid+1,t,p2);
d[0][p]=min(d[0][p1],d[0][p2]);
d[1][p]=min(d[1][p1],d[1][p2]);
}
void add(int x,int s,int t,int p,int c){
if(s==t){
d[0][p]=c-s;
d[1][p]=c+s;
return;
}
cl(p);
int mid=s+t>>1;
if(x<=mid)add(x,s,mid,p1,c);
if(mid+1<=x)add(x,mid+1,t,p2,c);
d[0][p]=min(d[0][p1],d[0][p2]);
d[1][p]=min(d[1][p1],d[1][p2]);
}
void update(int l,int r,int s,int t,int p,int c){
if(l>r)return;
if(l<=s&&t<=r){
d[0][p]+=c;
d[1][p]+=c;
b[p]+=c;
return;
}
cl(p);
int mid=s+t>>1;
if(mid>=l)update(l,r,s,mid,p1,c);
if(mid+1<=r)update(l,r,mid+1,t,p2,c);
d[0][p]=min(d[0][p1],d[0][p2]);
d[1][p]=min(d[1][p1],d[1][p2]);
}
int getsum(int l,int r,int s,int t,int p,int fg){
if(l<=s&&t<=r)return d[fg][p];
cl(p);
int mid=s+t>>1,as=1e18;
if(l<=mid)as=getsum(l,r,s,mid,p1,fg);
if(mid+1<=r)as=min(as,getsum(l,r,mid+1,t,p2,fg));
return as;
}
int query(int s,int t,int p){
if(s==t)return d[0][p]+s;
cl(p);
int mid=s+t>>1;
return min(query(s,mid,p1),query(mid+1,t,p2));
}
i_will ak IMO{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>q>>A>>B;
for(int i=1;i<=q;i++)cin>>a[i];
build(1,n,1);
for(int i=2;i<=q;i++){
int x=min(getsum(1,a[i],1,n,1,0)+a[i],getsum(a[i]+1,n,1,n,1,1)-a[i]);
add(a[i-1],1,n,1,x);
update(1,a[i-1]-1,1,n,1,abs(a[i]-a[i-1]));
update(a[i-1]+1,n,1,n,1,abs(a[i]-a[i-1]));
}
cout<<query(1,n,1);
i_ak ioi;
}

亲测可过,请勿抄袭!

题解:AT_arc073_d [ARC073F] Many Moves的更多相关文章

  1. AtCoder刷题记录

    构造题都是神仙题 /kk ARC066C Addition and Subtraction Hard 首先要发现两个性质: 加号右边不会有括号:显然,有括号也可以被删去,答案不变. \(op_i\)和 ...

  2. AtCoder瞎做第二弹

    ARC 067 F - Yakiniku Restaurants 题意 \(n\) 家饭店,\(m\) 张餐票,第 \(i\) 家和第 \(i+1\) 家饭店之间的距离是 \(A_i\) ,在第 \( ...

  3. 【arc073f】Many Moves(动态规划,线段树)

    [arc073f]Many Moves(动态规划,线段树) 题面 atcoder 洛谷 题解 设\(f[i][j]\)表示第一个棋子在\(i\),第二个棋子在\(j\)的最小移动代价. 发现在一次移动 ...

  4. Hdoj 1374.Knight Moves 题解

    Problem Description A friend of you is doing research on the Traveling Knight Problem (TKP) where yo ...

  5. HDU 1372 Knight Moves 题解

    Knight Moves Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  6. 题解 UVA439 骑士的移动 Knight Moves

    前言 最近板子题刷多了-- 题意 一个 \(8\times 8\) 的棋盘,问马从起点到终点的最短步数为多少. \(\sf Solution\) 要求最短路径嘛,显然 bfs 更优. 读入 这个读入处 ...

  7. [openjudge-搜索]Knight Moves(翻译与题解)

    题目描述(翻译) somurolov先生,精彩的象棋玩家.声称任何人他都可以从一个位置到另一个骑士这么快.你能打败他吗? 问题 你的任务是写一个程序来计算一个骑士达到从另一点所需要的最少步数,这样你就 ...

  8. 【ARC073F】Many Moves

    题目 一个显然的\(dp\),设\(dp_{i,j}\)表示其中一个棋子在\(x_i\)点,另一个棋子在\(j\)点的最小花费 显然\(dp_{i,j}\)有两种转移 第一种是把\(x_i\)上的棋子 ...

  9. LeetCode Minimum Moves to Equal Array Elements II

    原题链接在这里:https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/ 题目: Given a non-empt ...

  10. LeetCode Minimum Moves to Equal Array Elements

    原题链接在这里:https://leetcode.com/problems/minimum-moves-to-equal-array-elements/ 题目: Given a non-empty i ...

随机推荐

  1. HarmonyOS应用开发者高级认证【考题+答案】

    HarmonyOS应用开发者高级认证 前言 考试简介 掌握鸿蒙的核心概念和端云一体化开发.数据.网络.媒体.并发.分布式.多设备协同等关键技术能力,具备独立设计和开发鸿蒙应用能力. 博文说明 本博文的 ...

  2. go 组合函数 Collection

    我们经常需要程序在数据集上执行操作,比如选择满足给定条件的所有项,或者将所有的项通过一个自定义函数映射到一个新的集合上. 在某些语言中,会习惯使用泛型. Go 不支持泛型,在 Go 中,当你的程序或者 ...

  3. EmlBuilder:一款超轻量级的EML格式电子邮件阅读和编辑工具

    EmlBuilder 是一款超轻量级的电子邮件阅读和编辑工具,针对EML格式的文件具有非常强大的解析和容错能力,可实现超文本邮件的编写,并具备内嵌图片的编辑功能.该工具内部使用EmlParse对电子邮 ...

  4. BUUCTF---checkln(ROT加密)

    题目 dikqTCpfRjA8fUBIMD5GNDkwMjNARkUwI0BFTg== 解题 1.看见有==,尝试base64解码,但解码失败 2.尝试其它Base加密均失败 3.重新思考有等于号的加 ...

  5. study Rust-6【使用结构体组织相关联的数据】

    struc(structure) 定义并且实例化结构体: struct User { username: String, email: String, sign_in_count: u64, acti ...

  6. 运维必备:基于 Harbor 的 Helm Charts 批量拉取,从配置到自动化脚本

    引言 在企业级 Kubernetes 环境中,Harbor 作为主流的镜像与 Helm Chart 管理工具,常被用于存储 Helm Charts.但在迁移.备份或离线部署场景中,批量拉取 Harbo ...

  7. emmy断点调试

    package.cpath = package.cpath .. ';C:/Users/Administrator/AppData/Roaming/JetBrains/IntelliJIdea2021 ...

  8. 定时任务Cron表达式工具类Cron Util

    依赖 cron-utils的github地址:https://github.com/jmrozanec/cron-utils <dependency> <groupId>com ...

  9. 腾讯CodeBuddy,一款自带MCP市场的编程助手

    今天我发现了一个非常实用的腾讯云编程助手--CodeBuddy.之前它的名称是腾讯云代码助手,但现在已经正式更名为CodeBuddy,并且在更名的同时,其功能也得到了显著增强.今天,我们将详细了解一下 ...

  10. 【记录】Python3|Windows下Python3.11.0的pybluez安装(用于处理蓝牙模块的数据)

    参考: 官方安装文档:https://github.com/pybluez/pybluez/blob/master/docs/install.rst 仓库的issue447:https://githu ...