题意

Language:Default
Fence Obstacle Course
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 2900 Accepted: 1042

Description

Farmer John has constructed an obstacle course for the cows' enjoyment. The course consists of a sequence of N fences (1 <= N <= 50,000) of varying lengths, each parallel to the x axis. Fence i's y coordinate is i.



The door to FJ's barn is at the origin (marked '*' below). The starting point of the course lies at coordinate (S,N).


+-S-+-+-+ (fence #N)

+-+-+-+ (fence #N-1)

... ...

+-+-+-+ (fence #2)

+-+-+-+ (fence #1)

=|=|=|=*=|=|=| (barn)

-3-2-1 0 1 2 3

FJ's original intention was for the cows to jump over the fences, but cows are much more comfortable keeping all four hooves on the ground. Thus, they will walk along the fence and, when the fence ends, they will turn towards the x axis and continue walking in a straight line until they hit another fence segment or the side of the barn. Then they decide to go left or right until they reach the end of the fence segment, and so on, until they finally reach the side of the barn and then, potentially after a short walk, the ending point.



Naturally, the cows want to walk as little as possible. Find the minimum distance the cows have to travel back and forth to get from the starting point to the door of the barn.

Input

* Line 1: Two space-separated integers: N and S (-100,000 <= S <= 100,000)



* Lines 2..N+1: Each line contains two space-separated integers: A_i and B_i (-100,000 <= A_i < B_i <= 100,000), the starting and ending x-coordinates of fence segment i. Line 2 describes fence #1; line 3 describes fence #2; and so on. The starting position will satisfy A_N <= S <= B_N. Note that the fences will be traversed in reverse order of the input sequence.

Output

* Line 1: The minimum distance back and forth in the x direction required to get from the starting point to the ending point by walking around the fences. The distance in the y direction is not counted, since it is always precisely N.

Sample Input

4 0
-2 1
-1 2
-3 0
-2 1

Sample Output

4

Hint

This problem has huge input data,use scanf() instead of cin to read data to avoid time limit exceed.



INPUT DETAILS:



Four segments like this:


+-+-S-+ Fence 4

+-+-+-+ Fence 3

+-+-+-+ Fence 2

+-+-+-+ Fence 1

|=|=|=*=|=|=| Barn

-3-2-1 0 1 2 3

OUTPUT DETAILS:



Walk positive one unit (to 1,4), then head toward the barn, trivially going around fence 3. Walk positive one more unit (to 2,2), then walk to the side of the barn. Walk two more units toward the origin for a total of 4 units of back-and-forth walking.

Source

分析

参照逐梦起航-带梦飞翔的题解,线段树优化DP

设f[i][0/1]表示在通过第i条栅栏后,处于栅栏左边/右边的最小路径长。

因为奶牛是直线下来的,所以最优方案当然是从上一个栅栏的这个位置下来。由于有栅栏的影响,奶牛们不能顺利的下来,此时到达这个位置的最优策略要么是从前面那个栅栏的左端点过来,要么从右端点过来。所以有

\[f[i][0]=\min\{f[j][0]+|l_i-l_j|,f[j][1]+|l_i-r_j|\} \\
f[i][1]=\min\{f[j][0]+|r_i-l_j|,f[j][1]+|r_i-r_j|\}
\]

其中的j就是上一个挡住了这个位置的栅栏。我们可以用线段树来维护这个栅栏的编号。当栅栏(l[i],r[i]),出现后,我们把线段树上(l[i],r[i])这段区间改成i,表示这个位置是栅栏i阻挡了。对于后面的栅栏,修改时直接覆盖前面的信息即可。我们只要实现一个改段求点的线段树即可。

特别的,线段树初始值为0。一个位置如果得到的j=0,那么说明它前面没有栅栏,它可以直接从s过来,路径=abs(s-p)。

时间复杂度\(O(n\log s)\),也可以用线段树连边跑最短路,但这题用DP来做常数小。

代码

#include<iostream>
#include<cmath>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std; co int N=5e4+1,S=2e5+1,X=1e5;
int n,s,l[N],r[N],f[N][2];
struct T {int l,r,x;}t[S*4];
void build(int p,int l,int r){
t[p].l=l,t[p].r=r,t[p].x=l==r?0:-1;
if(l==r) return;
int mid=l+r>>1;
build(p<<1,l,mid),build(p<<1|1,mid+1,r);
}
void change(int p,int l,int r,int x){
if(l<=t[p].l&&t[p].r<=r) return t[p].x=x,void();
if(t[p].x!=-1) t[p<<1].x=t[p<<1|1].x=t[p].x,t[p].x=-1;
int mid=t[p].l+t[p].r>>1;
if(l<=mid) change(p<<1,l,r,x);
if(r>mid) change(p<<1|1,l,r,x);
}
int ask(int p,int x){
if(t[p].l==t[p].r) return t[p].x;
if(t[p].x!=-1) t[p<<1].x=t[p<<1|1].x=t[p].x,t[p].x=-1;
int mid=t[p].l+t[p].r>>1;
return ask(x<=mid?p<<1:p<<1|1,x);
}
int main(){
read(n),read(s);
build(1,0,X*2);
s+=X,l[0]=r[0]=X;
for(int i=1,w;i<=n;++i){
l[i]=read<int>()+X,r[i]=read<int>()+X;
w=ask(1,l[i]);
f[i][0]=min(f[w][0]+abs(l[i]-l[w]),f[w][1]+abs(l[i]-r[w]));
w=ask(1,r[i]);
f[i][1]=min(f[w][0]+abs(r[i]-l[w]),f[w][1]+abs(r[i]-r[w]));
change(1,l[i],r[i],i);
}
printf("%d\n",min(f[n][0]+s-l[n],f[n][1]+r[n]-s));
return 0;
}

最新文章

  1. alias导致virtualenv异常的分析和解法
  2. 手把手教从零开始在GitHub上使用Hexo搭建博客教程(二)-Hexo参数设置
  3. ZooKeeper日志与快照文件简单分析
  4. 关于对于IT我自己的见解以及我踩过的坑(需要认真读文章才能理解我所遇到的坑.)
  5. Mispelling 1510
  6. Linux下的NFS配置(转)
  7. angular 和jq 的AJAX的请求区别
  8. webkit和xcode
  9. android studio环境搭建-笔记1
  10. jquery插件tab——小试牛刀
  11. 三、MapReduce学习
  12. 日志分析工具Log Parser介绍
  13. 页面间固定参数,通过cookie传值
  14. C# 并行循环
  15. Jmeter对SQL Server进行压力测试
  16. iOS开发笔记(Swift)-通用App安装引导页的实现
  17. 获取链接的参数,判断是否是微信打开,ajax获取数据
  18. MySql 错误代码 1045
  19. tomcat6url请求400错误(%2F与%5C)
  20. SQL之group by

热门文章

  1. uva10537 dijkstra + 逆推
  2. .net webform 把word转为html
  3. navicat中文破解版,navicat破解版,navicat for mysql10.0.11简体中文破解版
  4. JS地址自动返填技术
  5. 开源工具-Json 解析器 Jackson 的使用
  6. Opencv3_Learning
  7. jquery chosen 插件 动态设置+更新选项值
  8. angular的路由和监听路由的变化和用户超时的监听
  9. JSP 表单处理
  10. DOM window的事件和方法; Rails查询语法query(查询结构继承); turbolinks的局限;