设dp[i][y]表示一个点在x[i],另一个点在y时最小要走的步数

那么有以下转移

对于y != x[i-1]的状态,可以证明,他们直接加|x[i] - x[i-1]|即可(如果有其他方案,不符合对dp的定义)

当y == x[i-1]时,它可以由其他所有状态转移过来, dp[i][x[i-1]] = min(dp[i][y] + |y - x[i]|)

把绝对值拆出来,就是需要维护一个dp[i][y] + y 和dp[i][y] - y,建立两个线段树即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long LL;
const int maxn = 2e5 + ;
LL Plus[maxn*], Minus[maxn*], tag[maxn*];
inline LL abs(LL x) { return x < ? -x : x; }
inline void Puttag(int o, LL v){
Plus[o] += v;
Minus[o] += v;
tag[o] += v;
}
inline void Pushdown(int o){
if(!tag[o]) return;
Puttag(o*, tag[o]);
Puttag(o*+, tag[o]);
tag[o] = ;
}
inline void Maintain(int o){
Plus[o] = min(Plus[o*], Plus[o*+]);
Minus[o] = min(Minus[o*], Minus[o*+]);
}
inline bool Cut(int x) { return false; }
inline bool Check(int x) { return true; }
inline void Change(int o, int l, int r, int L, int R, LL v){
if(L > r || R < l || Cut(o)) return;
if(L <= l && r <= R && Check(o)){
Puttag(o, v); return;
}
int mid = (l+r)/; Pushdown(o);
Change(o*, l, mid, L, R, v);
Change(o*+, mid+, r, L, R, v);
Maintain(o);
}
inline long long Query(int o, int l, int r, int L, int R, int ty){
if(L > r || R < l || Cut(o)) return 1e18;
if(L <= l && r <= R){
return ty ? Plus[o] : Minus[o];
}
int mid = (l+r)/; Pushdown(o);
ans = min(Query(o*+, mid+, r, L, R, ty), Query(o*, l, mid, L, R, ty));
Maintain(o);
return ans;
}
inline void Insert(int o, int l, int r, int k, LL v, int ty){
if(l == r) {
if(ty) Plus[o] = v; else Minus[o] = v;
return;
}
int mid = (l+r)/; Pushdown(o);
if(k <= mid) Insert(o*, l, mid, k, v, ty);
else Insert(o*+, mid+, r, k, v, ty);
Maintain(o);
} int N, Q, A, B;
int x[maxn];
int main(){
scanf("%d %d %d %d", &N, &Q, &A, &B);
for(int i = ; i <= Q; i++) scanf("%d", &x[i]);
x[] = B;
// dp[i][x] = dp[i-1][x] + ||
// dp[i][x[i-1]] = all(dp[i-1][x]+|x-x[i]|)
// x <= x[i] -> dp[i-1][x] + x[i] - x
// x > x[i] -> dp[i-1][x] + x - x[i]
memset(Plus, , sizeof(Plus));
memset(Minus, , sizeof(Minus));
Insert(, , N, A, A, );
Insert(, , N, A, -A, );
for(int i = ; i <= Q; i++){
LL ans = min(Query(, , N, , x[i], ) + x[i], Query(, , N, x[i]+, N, ) - x[i]);
Change(, , N, , x[i-]-, abs(x[i] - x[i-]));
Change(, , N, x[i-]+, N, abs(x[i] - x[i-])); Insert(, , N, x[i-], ans + x[i-], );
Insert(, , N, x[i-], ans - x[i-], );
}
LL ans = 1e18;
for(int i = ; i <= N; i++){
ans = min(ans, Query(, , N, i, i, ) + i);
}
cout<<ans<<endl;
}

arc073 F many moves(dp + 线段树)的更多相关文章

  1. ZOJ 3349 Special Subsequence 简单DP + 线段树

    同 HDU 2836 只不过改成了求最长子串. DP+线段树单点修改+区间查最值. #include <cstdio> #include <cstring> #include ...

  2. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  3. cf834D(dp+线段树区间最值,区间更新)

    题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...

  4. Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树)

    Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树) 题目链接 题意 给定一个nm的矩阵,每行取2k的矩阵,求总 ...

  5. Codeforces Round #530 (Div. 2) F (树形dp+线段树)

    F. Cookies 链接:http://codeforces.com/contest/1099/problem/F 题意: 给你一棵树,树上有n个节点,每个节点上有ai块饼干,在这个节点上的每块饼干 ...

  6. [CSP-S模拟测试]:F(DP+线段树)

    题目传送门(内部题49) 输入格式 第一行四个整数$n,q,a,b$.接下来$n$行每行一个整数$p_i$. 输出格式 一行一个整数表示答案. 样例 样例输入: 10 3 3 7 样例输出: 数据范围 ...

  7. Codeforces Round #530 (Div. 2)F Cookies (树形dp+线段树)

    题:https://codeforces.com/contest/1099/problem/F 题意:给定一个树,每个节点有俩个信息x和t,分别表示这个节点上的饼干个数和先手吃掉这个节点上一个饼干的的 ...

  8. [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)

    题目:http://poj.org/problem?id=3171 题意:给你n个区间[a,b],每个区间都有一个费用c,要你用最小的费用覆盖区间[M,E] 分析:经典的区间覆盖问题,百度可以搜到这个 ...

  9. 【uva1502/hdu4117-GRE Words】DP+线段树优化+AC自动机

    这题我的代码在hdu上AC,在uva上WA. 题意:按顺序输入n个串以及它的权值di,要求在其中选取一些串,前一个必须是后一个的子串.问d值的和最大是多少. (1≤n≤2×10^4 ,串的总长度< ...

随机推荐

  1. CentOS7 安装 Docker,10分钟入门!

    本次安装是在VM虚拟机的CentOS 7环境下,仅为了学习和测试的简单安装,如果在真实生产环境还需要考虑安全策略的其他问题. 1.Linux内核版本需要 3.10.0 以上并且是64位 [root@l ...

  2. js继承的几种方法和es6继承方法

        一.原型链继     1.基本思想     利用原型链来实现继承,超类的一个实例作为子类的原型     2.具体实现     function F() {}     //原型属性,原型方法: ...

  3. 搭建ssm框架经验

    要想搭建好ssm框架的开发环境.首先我们需要知道ssm是什么?ssm就是spring,springmvc,mybatis. 然后我们要知道,他们分别都是怎样实现的和做什么用的,充当什么角色?这样我们就 ...

  4. chrome debugger 调试

    debugger 使用chrome调试时,html页面的js代码中可能不好打断点(因为在jvm中才会有代码) 我一开始是故意在需要断点的后面或前面写个错的alert,通过jvm找到此处,然后在需要的地 ...

  5. Apache Maven(五):插件

    Maven的插件分如下两种: build plugins:该插件在项目构建阶段执行,它们都在<build>标签中设置. reporting plugins : 该插件在网站生成期间执行,他 ...

  6. 2.5 进程控制之wait函数

    一.绪论 一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果 是正常终止则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是 ...

  7. linux实现DNS轮询实现负载平衡

    DNS 轮询机制会受到多方面的影响,如:A记录的TTL时间长短的影响:别的 DNS 服务器 Cache 的影响:windows 客户端也有一个DNS Cache.这些都会影响 DNS 轮询的效果.因此 ...

  8. JAVA 基础编程练习题

    1 [程序 1 不死神兔] 题目:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少?程序分析: 兔子的规 ...

  9. mybatis 打印SQL

    如果使用的是application.properties文件,加入如下配置: #打印SQL logging.level.com.jn.ssr.supererscuereporting.dao=debu ...

  10. Eclipse 导入项目与 svn 插件关联全过程记录

    文章摘自:http://www.cnblogs.com/xmmcn/archive/2013/03/01/2938365.html 感谢博友分享! Eclipse 导入项目与 svn 插件关联全过程记 ...