arc073 F many moves(dp + 线段树)
设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 + 线段树)的更多相关文章
- ZOJ 3349 Special Subsequence 简单DP + 线段树
同 HDU 2836 只不过改成了求最长子串. DP+线段树单点修改+区间查最值. #include <cstdio> #include <cstring> #include ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- cf834D(dp+线段树区间最值,区间更新)
题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...
- Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树)
Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树) 题目链接 题意 给定一个nm的矩阵,每行取2k的矩阵,求总 ...
- Codeforces Round #530 (Div. 2) F (树形dp+线段树)
F. Cookies 链接:http://codeforces.com/contest/1099/problem/F 题意: 给你一棵树,树上有n个节点,每个节点上有ai块饼干,在这个节点上的每块饼干 ...
- [CSP-S模拟测试]:F(DP+线段树)
题目传送门(内部题49) 输入格式 第一行四个整数$n,q,a,b$.接下来$n$行每行一个整数$p_i$. 输出格式 一行一个整数表示答案. 样例 样例输入: 10 3 3 7 样例输出: 数据范围 ...
- Codeforces Round #530 (Div. 2)F Cookies (树形dp+线段树)
题:https://codeforces.com/contest/1099/problem/F 题意:给定一个树,每个节点有俩个信息x和t,分别表示这个节点上的饼干个数和先手吃掉这个节点上一个饼干的的 ...
- [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)
题目:http://poj.org/problem?id=3171 题意:给你n个区间[a,b],每个区间都有一个费用c,要你用最小的费用覆盖区间[M,E] 分析:经典的区间覆盖问题,百度可以搜到这个 ...
- 【uva1502/hdu4117-GRE Words】DP+线段树优化+AC自动机
这题我的代码在hdu上AC,在uva上WA. 题意:按顺序输入n个串以及它的权值di,要求在其中选取一些串,前一个必须是后一个的子串.问d值的和最大是多少. (1≤n≤2×10^4 ,串的总长度< ...
随机推荐
- Modify the apache2 default document and home page on ubuntu (ubuntu下修改apache2默认目录和默认主页)
Change the apache2 default website directory As we know, The apache2 default directory at /var/www/, ...
- 01 shell编程规范与变量
前言: 大家对shell脚本应该都不算陌生了,如果突然问你什么是shell脚本?是干什么用的?由什么组成以及怎么使用?变量的概念是什么?作用范围是什么?变量间的算术运算怎么表示?你能很容易答出来吗 本 ...
- jQuery-qrcode.js 生成带Logo 的二维码
引入文件 jQuery-qrcode.js 地址:https://blog-static.cnblogs.com/files/kitty-blog/jquery-qrcode.js https:// ...
- laydate js动态添加时间
$("#test2").click(function(){ var input=$('<input/>'); $("#test1").append( ...
- Laravel-admin 当使用Form组件hasMany的时候 进行编辑出现错误 foreach错误的时候解决方案
我的关联关系原名是 goodImage 修改成 image 之后解决问题 分析得出应该是 laravel会将goodImage 转成 good_image字段 这样就foreach会报错 所以出 ...
- red hat 7 启动过程(EFI)
不同版本的Linux系统的启动过程在某些地方是不一样的,现在先来介绍一下red hat 7 的启动过程(EFI). (加电→图形登录界面) 接通电源 按下电源键 EFI固件启动 初始化硬件 从EFI启 ...
- nyoj 525 一道水题【字符串(分割)】
参考:https://blog.csdn.net/dxx_111/article/details/48154687 #include <iostream> #include <cst ...
- Grok Debugger本地安装(转载)
原文链接:http://fengwan.blog.51cto.com/508652/1758845 最近在使用ELK对日志进行集中管理,因为涉及到日志的规则经常要用到http://grokdebug. ...
- 再谈js传值和传址
js的传值和传址还是真绕,前回文说道 1.值类型是传值的 2.对象和数组是传址的 这两点通过例子的到了证实 然而还有一种情况没有讨论 即 函数的参数的传值和传址 通过实验,在函数中用一个新对象去覆盖传 ...
- OpenCV代码提取:transpose函数的实现
OpenCV中的transpose函数实现图像转置,公式为: 目前fbc_cv库中也实现了transpose函数,支持多通道,uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一 ...