acwing329 围栏障碍训练场 题解
考试压轴题,意识到这题是线段树优化 \(dp\) 时追悔莫及。
为了简化题目,我将从起点到原点变成了从原点到起点(这样就可以省去两个数组的空间)。
想到设 \(dp_{i,j}\) 表示在第 \(i\) 层,奶牛们在 \(j\) 列时的最小移动范围,则转移方程为(设输入为 \(l,r\)):
dp_{i,j}=dp_{i-1,j}\ (j\ne l,r)\\
dp_{i,l}=\min(dp_{i-1,l},\min\limits_{k=l+1}^{r-1}(dp_{i-1,k}+k-l))\\
dp_{i,r}=\min(dp_{i-1,r},\min\limits_{k=l+1}^{r-1}(dp_{i-1,k}+r-k))
\end{cases}
\]
发现可以通过线段树优化 \(dp\),时间复杂度 \(O(n\log_2 2\times 10^5)\)。
#include<bits/stdc++.h>
#define ll long long
#define ls(x) x*2
#define rs(x) x*2+1
using namespace std;
const int N=2e6+5;
int n,s,lb[N];
int lmn[N],rmn[N];
void push_down(int x){
if(!lb[x]) return;
lb[ls(x)]=lb[rs(x)]=1;
lmn[ls(x)]=rmn[ls(x)]=1e9;
lmn[rs(x)]=rmn[rs(x)]=1e9;
lb[x]=0;return;
}void build(int x,int l,int r){
lmn[x]=rmn[x]=1e9;
if(l==r) return;
build(ls(x),l,(l+r-1)/2);
build(rs(x),(l+r-1)/2+1,r);
}void add(int x,int l,int r,int a,int k){
if(l==r){
lb[x]=0;lmn[x]=min(lmn[x],k);
rmn[x]=min(rmn[x],k);return;
}push_down(x);int m=(l+r-1)/2;
if(a<=m) add(ls(x),l,m,a,k);
else add(rs(x),m+1,r,a,k);
lmn[x]=min(lmn[ls(x)],lmn[rs(x)]+m-l+1);
rmn[x]=min(rmn[ls(x)]+r-m,rmn[rs(x)]);
}int lmin(int x,int l,int r,int L,int R){
if(L<=l&&r<=R) return lmn[x];
push_down(x);int m=(l+r-1)/2;
if(R<=m) return lmin(ls(x),l,m,L,R);
if(L>m) return lmin(rs(x),m+1,r,L,R);
int lm=lmin(ls(x),l,m,L,R);
int rm=lmin(rs(x),m+1,r,m+1,R);
return min(lm,rm+m-L+1);
}int rmin(int x,int l,int r,int L,int R){
if(L<=l&&r<=R) return rmn[x];
push_down(x);int m=(l+r-1)/2;
if(R<=m) return rmin(ls(x),l,m,L,R);
if(L>m) return rmin(rs(x),m+1,r,L,R);
int lm=rmin(ls(x),l,m,L,m);
int rm=rmin(rs(x),m+1,r,L,R);
return min(lm+R-m,rm);
}void turn(int x,int l,int r,int L,int R){
if(L<=l&&r<=R){
lmn[x]=rmn[x]=1e9;
lb[x]=1;return;
}push_down(x);int m=(l+r-1)/2;
if(L<=m) turn(ls(x),l,m,L,R);
if(R>m) turn(rs(x),m+1,r,L,R);
}int que(int x,int l,int r,int a){
if(l==r) return lmn[x];
int m=(l+r-1)/2;
if(a<=m) return que(ls(x),l,m,a);
return que(rs(x),m+1,r,a);
}int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>s;
build(1,-1e5,1e5);
add(1,-1e5,1e5,0,0);
for(int i=1;i<=n;i++){
int l,r;cin>>l>>r;
if(l+2>r) continue;
int lm=lmin(1,-1e5,1e5,l+1,r-1);
int rm=rmin(1,-1e5,1e5,l+1,r-1);
turn(1,-1e5,1e5,l+1,r-1);
add(1,-1e5,1e5,l,lm+1);
add(1,-1e5,1e5,r,rm+1);
}int lm=lmin(1,-1e5,1e5,s+1,1e5);
int rm=rmin(1,-1e5,1e5,-1e5,s-1);
add(1,-1e5,1e5,s,min(lm,rm)+1);
cout<<que(1,-1e5,1e5,s);
return 0;
}
acwing329 围栏障碍训练场 题解的更多相关文章
- AcWing 329. 围栏障碍训练场
大型补档计划 题目链接 考虑模拟这个过程. \(f[i][0 / 1]\) 表示从第 \(i\) 个围栏的 左/右端点开始往下走,走到原点的最小花费. 转移很容易想到,就是考虑找到一个往下走第一个碰到 ...
- [TCO2013]Block3Checkers
题意:一个网格上有一些障碍和$3$个在网格边界上的棋子,你要添加一些障碍使得没有两个棋子四连通,问最少添加多少个障碍 官方题解——一张图教你做人... 三个棋子将网格边界分成三段,添加障碍后网格中一定 ...
- BZOJ1591 & 洛谷2924:[USACO2008 DEC]Largest Fence 最大的围栏——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1591 https://www.luogu.org/problemnew/show/P2924#sub ...
- [USACO07OCT]障碍路线 & yzoj P1130 拐弯 题解
题意 给出n* n 的图,A为起点,B为终点,* 为障碍,.可以行走,问最少需要拐90度的弯多少次,无法到达输出-1. 解析 思路:构造N * M * 4个点,即将原图的每个点分裂成4个点.其中点(i ...
- ACM/ICPC 之 BFS-简单障碍迷宫问题(POJ2935)
题目确实简单,思路很容易出来,难点在于障碍的记录,是BFS迷宫问题中很经典的题目了. POJ2935-Basic Wall Maze 题意:6*6棋盘,有三堵墙,求从给定初始点到给定终点的最短路,输出 ...
- 2016多校第六场题解(hdu5793&hdu5794&hdu5795&hdu5800&hdu5802)
这场就做出一道题,怎么会有窝这么辣鸡的人呢? 1001 A Boring Question(hdu 5793) 很复杂的公式,打表找的规律,最后是m^0+m^1+...+m^n,题解直接是(m^(n+ ...
- UVA 1600 Patrol Robot(机器人穿越障碍最短路线BFS)
UVA 1600 Patrol Robot Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu ...
- BZOJ 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课
题目 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课 Time Limit: 5 Sec Memory Limit: 64 MB Description 考虑一 ...
- 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课
1644: [Usaco2007 Oct]Obstacle Course 障碍训练课 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 383 Solved ...
- “盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛题解&&源码【A,水,B,水,C,水,D,快速幂,E,优先队列,F,暴力,G,贪心+排序,H,STL乱搞,I,尼姆博弈,J,差分dp,K,二分+排序,L,矩阵快速幂,M,线段树区间更新+Lazy思想,N,超级快速幂+扩展欧里几德,O,BFS】
黑白图像直方图 发布时间: 2017年7月9日 18:30 最后更新: 2017年7月10日 21:08 时间限制: 1000ms 内存限制: 128M 描述 在一个矩形的灰度图像上,每个 ...
随机推荐
- InheritableThreadLocal 父子线程值传递
最近项目中使用 @Async 异步远程调用的时候,发现主线程能拿到 token 值,子线程调用的时候 token 为 null.研究了一番,发现可以直接使用 InheritableThreadLoca ...
- jsp移动端和pc端页面判断及切换
function goPAGE() { if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobi ...
- 【Amadeus原创】centos中挖矿病毒kdevtmpfsi的终极解决方法
试了很久,最终的解决方法如下: 1,编写sh脚本:rm_wk.sh #!/bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr ...
- 基于 MediatR 和 FluentValidation 的 CQRS 验证管线
基于 MediatR 和 FluentValidation 的 CQRS 验证管线 CQRS Validation Pipeline with MediatR and FluentValidation ...
- mongodb和spring集成中MongoTemplate的总结是使用方法
基础实体类@Document(collection="person") class Person{ String id; String name; int age; public ...
- Qt/C++中英输入法/嵌入式输入法/小数字面板/简繁切换/特殊字符/支持Qt456
一.前言 在嵌入式板子上由于没有系统层面的输入法支持,所以都绕不开一个问题,那就是在需要输入的UI软件中,必须提供一个输入法来进行输入,大概从Qt5.7开始官方提供了输入法的源码,作为插件的形式加入到 ...
- 循规蹈矩--从零开始建设k8s监控(一)
前言 监控k8s集群,目前主流就是使用prometheus以及其周围的生态,本文开始介绍怎么一步步完成k8s监控的建设 环境准备 组件 版本 操作系统 Ubuntu 22.04.4 LTS minik ...
- Eclipse中如何将web应用部署到tomcat
第1种方法: 将workspace下的复制到tomcat的webapp下(我看度还是算了,看着都觉得麻烦). 第2种方法:总体思路就是:(1)先为web应用创建Tomcat Server:(2)再将w ...
- [转]JDBC与MySQL数据库
原文链接: 1.JAVA程序与MySQL数据库链接的基本操作详细演示与说明 2.Java JDBC连接数据库(数据库信息读取property文件) 3.JDBC与数据库
- IM群聊消息的已读未读功能在存储空间方面的实现思路探讨
1.引言 IM系统中,特别是在企业应用场景下,消息的已读未读状态是一个强需求. 以阿里的钉钉为例,钉钉的产品定位是用于商务交流,其"强制已读回执"功能,让职场人无法再"假 ...