题目链接

POJ2374

题解

题意:

给出\(n\)个平行于\(x\)轴的栅栏,求从一侧栅栏的某个位置出发,绕过所有栅栏到达另一侧\(x = 0\)位置的最短水平距离

往上说都是线段树优化dp

我写了一个奇怪的线段树过了,似乎并没有和dp沾边

因为每次都是从某个栅栏的端点出发,到达某个位置的值等于[所有这些可出发的端点已产生的代价 + 到达这个点的距离] 的最小值

就用线段树维护每个区间

\(lm[u]\)表示在这个区间内的端点到达左端点的最小代价

\(rm[u]\)表示到右端点的最小代价

然后每出现一层栅栏,计算出左右端点来更新线段树,同时清空被新栅栏覆盖的区间【因为这些端点已经无法直接到达下一层区间了】

PS:

一开始看错题了,栅栏的顺序是反过来的

在察觉看错题之前,拿了往上若干AC程序对拍

拍出一个惊人小数据,竟所有程序输出都不一样!!

5 0

3 4

-4 5

-4 0

1 3

2 3

最终画图钦定,,我把它们hack掉了

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define cls(s) memset(s,0,sizeof(s))
#define ls (u << 1)
#define rs (u << 1 | 1)
using namespace std;
const int maxn = 200005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
const int ll = 1,rr = 200001,P = 100001;
int lm[maxn << 2],rm[maxn << 2],tag[maxn << 2];
void upd(int u,int l,int r){
int mid = l + r >> 1;
lm[u] = min(lm[ls],lm[rs] + (mid - l + 1));
rm[u] = min(rm[rs],rm[ls] + (r - mid));
}
void pd(int u){
if (tag[u]){
lm[ls] = rm[ls] = lm[rs] = rm[rs] = INF;
tag[ls] = tag[rs] = 1;
tag[u] = 0;
}
}
void modify(int u,int l,int r,int pos,int v){
if (l == r){
lm[u] = min(lm[u],v);
rm[u] = min(rm[u],v);
return;
}
pd(u);
int mid = l + r >> 1;
if (mid >= pos) modify(ls,l,mid,pos,v);
else modify(rs,mid + 1,r,pos,v);
upd(u,l,r);
}
void reset(int u,int l,int r,int L,int R){
if (l >= L && r <= R){lm[u] = rm[u] = INF; tag[u] = 1; return;}
pd(u);
int mid = l + r >> 1;
if (mid >= L) reset(ls,l,mid,L,R);
if (mid < R) reset(rs,mid + 1,r,L,R);
upd(u,l,r);
}
int query(int u,int l,int r,int pos){
if (l == r) return min(lm[u],rm[u]);
pd(u);
int mid = l + r >> 1;
if (mid >= pos) return min(lm[rs] + (mid - pos + 1),query(ls,l,mid,pos));
return min(rm[ls] + (pos - mid),query(rs,mid + 1,r,pos));
}
void build(int u,int l,int r){
if (l == r){lm[u] = rm[u] = INF; return;}
int mid = l + r >> 1;
build(ls,l,mid);
build(rs,mid + 1,r);
upd(u,l,r);
}
int ql[maxn],qr[maxn];
int main(){
int n,s,l,r,ld,rd;
while (~scanf("%d%d",&n,&s)){
s += P;
build(1,ll,rr);
modify(1,ll,rr,s,0);
for (int i = 1; i <= n; i++) ql[i] = read(),qr[i] = read();
for (int i = n; i; i--){
l = ql[i] + P; r = qr[i] + P;
ld = query(1,ll,rr,l);
rd = query(1,ll,rr,r);
if (l + 1 <= r - 1) reset(1,ll,rr,l + 1,r - 1);
modify(1,ll,rr,l,ld);
modify(1,ll,rr,r,rd);
}
printf("%d\n",query(1,ll,rr,P));
}
return 0;
}

POJ2374 Fence Obstacle Course 【线段树】的更多相关文章

  1. poj2374 Fence Obstacle Course[线段树+DP]

    https://vjudge.net/problem/POJ-2374 吐槽.在这题上面磕了许久..英文不好题面读错了qwq,写了个错的算法搞了很久..A掉之后瞥了一眼众多julao题解,**,怎么想 ...

  2. POJ 2374 Fence Obstacle Course(线段树+动态规划)

    Fence Obstacle Course Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 2524   Accepted:  ...

  3. POJ2374 Fence Obstacle Course

    题意 Language:Default Fence Obstacle Course Time Limit: 3000MS Memory Limit: 65536K Total Submissions: ...

  4. 【BZOJ3387】[Usaco2004 Dec]Fence Obstacle Course栅栏行动 线段树

    [BZOJ3387][Usaco2004 Dec]Fence Obstacle Course栅栏行动 Description 约翰建造了N(1≤N≤50000)个栅栏来与牛同乐.第i个栅栏的z坐标为[ ...

  5. (困难) CF 484E Sign on Fence,整体二分+线段树

    Bizon the Champion has recently finished painting his wood fence. The fence consists of a sequence o ...

  6. Gym 101911E "Painting the Fence"(线段树区间更新+双端队列)

    传送门 题意: 庭院中有 n 个围栏,每个围栏上都被涂上了不同的颜色(数字表示): 有 m 条指令,每条指令给出一个整数 x ,你要做的就是将区间[ x第一次出现的位置 , x最后出现的位置 ]中的围 ...

  7. 「CF484E」Sign on Fence「整体二分」「线段树」

    题意 给定一个长度为\(n\)的正整数序列,第\(i\)个数为\(h_i\),\(m\)个询问,每次询问\((l, r, w)\),为\([l, r]\)所有长度为\(w\)的子区间最小值的最大值.( ...

  8. Fence Obstacle Course

    Fence Obstacle Course 有n个区间自下而上有顺序的排列,标号\(1\sim n\),第i个区间记做\([l_i,r_i]\),现在从第n个区间的起点s出发(显然s在\([l_n,r ...

  9. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

随机推荐

  1. BZOJ1053: [HAOI2007]反素数ant(爆搜)

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4163  Solved: 2485[Submit][Status][Discuss] Descript ...

  2. mariadb源码编译安装及多实例

    准备文件源文件/app/mariadb-10.2.12.tar.gz cd /app/ tar xf mariadb-10.2.12.tar.gz cd  mariadb-10.2.12 mkdir ...

  3. tcl之控制流-while

  4. 【PHP项目】伪静态规则

    伪静态规则写法RewriteRule-htaccess详细语法使用 2016年03月30日 16:53:59 阅读数:20340 伪静态实际上是利用php把当前地址解析成另一种方法来访问网站,要学伪静 ...

  5. elasticsearch 5.x 系列之七 基于索引别名的零停机升级服务

    一,写在前面的话,elasticsearch 建立索引时的Mapping 设置 建议你在设计索引的初期,就把索引的各个字段设计好,因为,elasticsearch 的各个字段,定义好类型后,就无法进行 ...

  6. 前言 openwrt简介

    什么是openwrt?先看一下度娘怎么说. OpenWRT是一个高度模块化.高度自动化的嵌入式Linux系统,拥有强大的网络组件和扩展性,常常被用于工控设备.电话.小型机器人.智能家居.路由器以及VO ...

  7. POJ:2100-Graveyard Design(尺取)

    Graveyard Design Time Limit: 10000MS Memory Limit: 64000K Total Submissions: 8504 Accepted: 2126 Cas ...

  8. java实时监听日志写入kafka(多目录)

    目的 实时监听多个目录下的日志文件,如有新文件切换到新文件,并同步写入kafka,同时记录日志文件的行位置,以应对进程异常退出,能从上次的文件位置开始读取(考虑到效率,这里是每100条记一次,可调整) ...

  9. python面向对象(进阶篇)

    本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员: 类的成员可以分为三大类:字段(变量).方法.属性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对 ...

  10. async/await 实现协程

    2. 基本了解 在了解异步协程之前,我们首先得了解一些基础概念,如阻塞和非阻塞.同步和异步.多进程和协程. 2.1 阻塞 阻塞状态指程序未得到所需计算资源时被挂起的状态.程序在等待某个操作完成期间,自 ...