Solution -「CodeChef JUMP」Jump Mission
\(\mathcal{Description}\)
Link.
有 \(n\) 个编号 \(1\sim n\) 的格子排成一排,并有三个权值序列 \(\{a_n\},\{h_n\},\{p_n\}\),其中 \(\{p_n\}\) 是一个排列。从 \(i\) 跳到 \(j\),必须满足 \(i<j\land p_i<p_j\),代价为 \((h_i-h_j)^2+a_j\),求从 \(1\) 跳到 \(n\) 的最小代价。
\(n,h_i\le6\times10^5\)。
\(\mathcal{Solution}\)
不就是个板子套板子吗你还水题解。
设 \(f(i)\) 表示从 \(1\) 跳到 \(i\) 的最小代价,显然
\]
转移条件是二维偏序关系,反手一个 CDQ,转移最优化的是一次函数,再丢一个李超树,复杂度 \(\mathcal O(n\log n\log h)\)。
比树套树好写不知道多少,而且跑得飞快。
\(\mathcal{Code}\)
/*~Rainybunny~*/
#include <bits/stdc++.h>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
inline char fgc() {
static char buf[1 << 17], *p = buf, *q = buf;
return p == q && ( q = buf + fread( p = buf, 1, 1 << 17, stdin ), p == q )
? EOF : *p++;
}
inline int rint() {
int x = 0, f = 1, s = fgc();
for ( ; s < '0' || '9' < s; s = fgc() ) f = s == '-' ? -f : f;
for ( ; '0' <= s && s <= '9'; s = fgc() ) x = x * 10 + ( s ^ '0' );
return x * f;
}
typedef long long LL;
inline void chkmin( LL& a, const LL b ) { b < a && ( a = b ); }
const int MAXN = 6e5;
const LL LINF = 1ll << 60;
int n, mxh, h[MAXN + 5], p[MAXN + 5], a[MAXN + 5];
LL f[MAXN + 5];
std::vector<int> ord[MAXN * 2 + 5];
struct Line {
LL k, b;
inline LL operator () ( const int x ) { return k * x + b; }
};
struct SegmentTree {
Line line[MAXN + 5];
int lcnt, vers, ver[MAXN << 2], idx[MAXN << 2];
inline void clear() { lcnt = 0, ++vers; }
inline void insert( const int u, const int l, const int r, int id ) {
if ( ver[u] != vers ) return idx[u] = id, ver[u] = vers, void();
int mid = l + r >> 1;
if ( line[idx[u]]( mid ) > line[id]( mid ) ) std::swap( idx[u], id );
if ( l == r ) return ;
if ( line[idx[u]]( l ) > line[id]( l ) ) {
insert( u << 1, l, mid, id );
} else if ( line[idx[u]]( r ) > line[id]( r ) ) {
insert( u << 1 | 1, mid + 1, r, id );
}
}
inline void insert( const Line& l ) {
line[++lcnt] = l, insert( 1, 1, mxh, lcnt );
}
inline LL query( const int u, const int l, const int r, const int x ) {
if ( ver[u] != vers ) return LINF;
LL ret = line[idx[u]]( x );
if ( l == r ) return ret;
int mid = l + r >> 1;
if ( x <= mid ) chkmin( ret, query( u << 1, l, mid, x ) );
else chkmin( ret, query( u << 1 | 1, mid + 1, r, x ) );
return ret;
}
} sgt;
#define id( l, r ) ( ( l + r ) | ( l != r ) )
inline void build( const int l, const int r ) {
int u = id( l, r ); ord[u].resize( r - l + 1 );
if ( l == r ) return void( ord[u][0] = l );
int mid = l + r >> 1, lc = id( l, mid ), rc = id( mid + 1, r );
build( l, mid ), build( mid + 1, r );
std::merge( ord[lc].begin(), ord[lc].end(), ord[rc].begin(), ord[rc].end(),
ord[u].begin(), []( const int x, const int y ) { return p[x] < p[y]; } );
}
inline void solve( const int l, const int r ) {
if ( l == r ) return ;
int mid = l + r >> 1;
solve( l, mid ), sgt.clear();
for ( int u: ord[id( l, r )] ) {
if ( u <= mid && f[u] != LINF ) {
sgt.insert( { -2ll * h[u], 1ll * h[u] * h[u] + f[u] } );
} else if ( u > mid ) {
chkmin( f[u], 1ll * h[u] * h[u] + a[u]
+ sgt.query( 1, 1, mxh, h[u] ) );
}
}
solve( mid + 1, r );
}
#undef id
int main() {
n = rint();
rep ( i, 1, n ) p[i] = rint();
rep ( i, 1, n ) a[i] = rint();
rep ( i, 1, n ) h[i] = rint(), mxh = std::max( mxh, h[i] );
f[1] = a[1];
rep ( i, 2, n ) f[i] = LINF;
build( 1, n ), solve( 1, n );
printf( "%lld\n", f[n] );
return 0;
}
Solution -「CodeChef JUMP」Jump Mission的更多相关文章
- Solution -「ARC 104E」Random LIS
\(\mathcal{Description}\) Link. 给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...
- Solution -「CTS 2019」「洛谷 P5404」氪金手游
\(\mathcal{Description}\) Link. 有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...
- Solution -「BZOJ 3812」主旋律
\(\mathcal{Description}\) Link. 给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...
- Solution -「CF 1342E」Placing Rooks
\(\mathcal{Description}\) Link. 在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...
- Solution -「简单 DP」zxy 讲课记实
魔法题位面级乱杀. 「JOISC 2020 Day4」治疗计划 因为是不太聪明的 Joker,我就从头开始理思路了.中途也会说一些和 DP 算法本身有关的杂谈,给自己的冗长题解找借口. 首先,治疗方案 ...
- Solution -「基环树」做题记录
写的大多只是思路,比较简单的细节和证明过程就不放了,有需者自取. 基环树简介 简单说一说基环树吧.由名字扩展可得这是一类以环为基础的树(当然显然它不是树. 通常的表现形式是一棵树再加一条非树边,把图画 ...
- 「CodeChef - SKIRES」Ski Resort
题目链接 戳我 \(Description\) 给你一个\(n*m\)的网格,以及网格上的两个格子\(A,B\).每个格子有一个高度.每次操作可以选择一个格子(不能是\(A\)或\(B\))并将它的高 ...
- Solution -「WC 2022」秃子酋长
\(\mathscr{Description}\) Link. (It's empty temporarily.) 给定排列 \(\{a_n\}\),\(q\) 次询问,每次给出 \([l,r ...
- Solution -「JSOI 2019」「洛谷 P5334」节日庆典
\(\mathscr{Description}\) Link. 给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的). \(|S|\le3\time ...
随机推荐
- react中antd+css Module一起使用
antd 和 css modules 不能混用,针对antd的css 单独写一条loader的规则,不开启 css modules. 使用 exclude 和 include 配置参考(https:/ ...
- SYCOJ27猴子选大王
题目-猴子选大王 (shiyancang.cn) 一.出队顺序Description有M个人,其编号分别为1-M.这M个人按顺序排成一个圈.现在给定一个数N,从第一个人开始依次报数,数到N的人出列,然 ...
- docker创建mysql容器时挂载文件路径后无法启动(已解决)
系统centos7 docker版本: 解决方法: 在docker run中加入 --privileged=true 给容器加上特定权限,如下 docker run --privileged=tru ...
- Android开发 海康威视 多路视频播放(同时播放视频)
原文地址:Android开发 海康视频 多路视频播放 | Stars-One的杂货小窝 最近公司有个项目需要对接到海康监控摄像头来实现对应的实时播放和回放,但这两个不是我们今天要讨论的重点,APP首页 ...
- TC (Teamcenter) 许可证解决方案
是否因为经常遇到下列许可问题而苦恼? 没有可用于Teamcenter 并发模块"catia_integration"的Flexlm许可证: Teamcenter Visualiza ...
- Xbatis:SpringBoot 数据管理框架
目录 安装 下载源码 编译源码 添加依赖 数据表 数据源 Xbatis XbatisManager Database/Table/Column Column Table Database Create ...
- Java加减乘除计算器实现
加减乘除计算机的实现 public static void main(String[] args) { while(true) { System.out.println("依次输入要计算的2 ...
- GeoServer课程规划
"凡事豫则立,不豫则废." --西汉·戴圣<礼记·中庸> 为了做好GeoServer课程培训,需要拟定一个课程目录,对整个课程做一个宏观上的规划.有了这个规划,就有了目 ...
- IoC容器-Bean管理XML方式(注入内部bean和级联赋值)
注入属性-内部bean和级联赋值 (1)一对多关系:部分和员工 一个部门有多个员工,一个员工属于一个部门 部门是一,员工是多 (2)在实体类之间表示一对多关系 (3)在spring配置文件中进行配置 ...
- ElasticSearch+Kibana+Packetbeat
一.介绍 Packetbeat 是一个实时网络数据包分析工具,通过嗅探应用服务器之间的网络通讯,来解码应用层协议类型如HTTP.MySQL.redis等等,关联请求与响应,并记录每个事务有意义的字段. ...