**开始天真的我以为这道题和运输计划是一样的套路。于是写了一发,debug后发现过了第一个点,十分开心的交了一发,结果只过了第一个点。后来发现这个并不是一样的,因为修建黑洞之后路径法变了,而运输计划没有(树上两点间路径唯一)。于是,第一题就成了题解题...

这道题显然满足二分性质。问题在与如何判断合法。

首先,\(<=mid\) 的路径肯定满足,对于不满足的路径 \(l\) 到 \(r\),一定是在 \(x\) 和 \(y\) 处修建黑洞以后,\(l\) -> \(x\) -> \(y\) -> \(r\),且满足不等式:

\[\left | l-x \right | + \left | r-y \right | <= mid
\]

解得:

\[y\in\left [ l+r-mid+x,r-l+mid-x \right ]\left ( l>=x \right )
\]

\[y\in\left [ r-l-mid+x,r+l+mid-x \right ]\left ( l<x \right )
\]

暴力的做法是枚举 \(x\),对于每一个区间求出 \(y\) 的取值范围,然后判断是否有交集。

但这样是 \(O(n^2)\) 的,需要优化。可以把区间分成两部分,前一部分 \(l<x\),后一部分 \(l>=x\),在两个部分分别求交集,再两部分的交集判断是否有交集。这样的话,前一部分的区间都有一个增量 \(x\),交集就是 \(l+r-mid\) 的交集再加上 \(x\),对于 \(l+r-mid\) 的交集可以 \(O(n)\) 预处理。后一部分同理。前一部分预处理处理前缀,后一部分后缀。

然后就可以 \(O(1)\) 判断两部分的交集是否有交集。**

#include <bits/stdc++.h>
using namespace std; #define db double
#define ll long long
#define RG register inline int gi()
{
RG int ret; RG bool flag; RG char ch;
ret=0, flag=true, ch=getchar();
while (ch < '0' || ch > '9')
ch == '-' ? flag=false : 0, ch=getchar();
while (ch >= '0' && ch <= '9')
ret=(ret<<3)+(ret<<1)+ch-'0', ch=getchar();
return flag ? ret : -ret;
} const db pi = acos(-1.0);
const int N = 5e5+5, inf = 1<<30; int n,m,cf[N],l1[N],r1[N];
struct range
{
int l,r;
inline bool operator <(const RG range &R) const { return l < R.l; }
}ra[N];
struct Range
{
int l,r,l1,l2,r1,r2;
}g[N]; inline bool check(RG int lim)
{
RG int i,cnt,p,l2,r2;
cnt=0;
for (i=1; i<=m; ++i)
{
if (ra[i].r-ra[i].l <= lim)
continue;
cnt++;
g[cnt].l=ra[i].l, g[cnt].r=ra[i].r;
g[cnt].l1=ra[i].l+ra[i].r-lim;
g[cnt].l2=ra[i].r-ra[i].l-lim;
g[cnt].r1=ra[i].r-ra[i].l+lim;
g[cnt].r2=ra[i].l+ra[i].r+lim;
} //预处理
p=cnt;
l1[n+1]=l2=-inf, r1[n+1]=r2=inf;
for (i=n; i; --i)
{
l1[i]=l1[i+1], r1[i]=r1[i+1];
while (p && g[p].l >= i)
{
l1[i] < g[p].l1 ? l1[i]=g[p].l1 : 0;
r1[i] > g[p].r1 ? r1[i]=g[p].r1 : 0;
p--;
}
} //预处理对于每一个x后一部分的解集
p=1;
for (i=1; i<=n; ++i)
{
while (p <= cnt && g[p].l <= i)
{
l2 < g[p].l2 ? l2=g[p].l2 : 0;
r2 > g[p].r2 ? r2=g[p].r2 : 0;
p++;
} //计算对于每一个x前一部分的解集
if (l1[i] <= r1[i]+(i<<1) && l2+(i<<1) <= r2
&& !((r1[i] < l2) || (l1[i] > r2)))
return true; //判断前后是否分别有解及两部分是否有交集
}
return false;
} int main()
{
freopen("trans.in","r",stdin);
freopen("trans.out","w",stdout);
n=gi(), m=gi();
RG int i,l,r,mid;
for (i=1; i<=m; ++i)
{
ra[i].l=gi(), ra[i].r=gi();
if (ra[i].l > ra[i].r)
swap(ra[i].l,ra[i].r);
}
sort(ra+1,ra+m+1);
l=0, r=n+1;
while (l <= r)
{
mid=(l+r)>>1;
if (check(mid))
r=mid-1;
else
l=mid+1;
}
printf("%d\n",r+1);
return 0;
}

51nod1671【货物运输】的更多相关文章

  1. [51nod1671]货物运输

    公元2222年,l国发生了一场战争. 小Y负责领导工人运输物资. 其中有m种物资的运输方案,每种运输方案形如li,ri.表示存在一种货物从li运到ri. 这里有n个城市,第i个城市与第i+1个城市相连 ...

  2. 【LCA&倍增】货物运输 @upcexam5909

    时间限制: 1 Sec 内存限制: 128 MB 题目描述 在一片苍茫的大海上,有n座岛屿,岛屿与岛屿之间由桥梁连接,所有的岛屿刚好被桥梁连接成一个树形结构,即共n-1架桥梁,且从任何一座岛屿出发都能 ...

  3. HDU 5699 货物运输 二分

    货物运输 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5699 Description 公元2222年,l国发生了一场战争. 小Y负责领导工人运输物 ...

  4. Django自学计划之集装箱货物运输物流仓储一站式ERP系统

    业余开始学习时间:2018年1月 业余学习时间段:每天下班晚饭后时间+无事的星期六和星期天+上班时的空闲时间 自学目标: 1.我们要用管理的思维来写我们的系统! 2.我们要用我们的ERP系统帮助中小集 ...

  5. 货物运输 51Nod - 1671

    公元2222年,l国发生了一场战争. 小Y负责领导工人运输物资. 其中有m种物资的运输方案,每种运输方案形如li,ri.表示存在一种货物从li运到ri. 这里有n个城市,第i个城市与第i+1个城市相连 ...

  6. HDU 5699 货物运输 二分判定

    转自:http://blog.csdn.net/jtjy568805874/article/details/51480479 #include <cstdio> #include < ...

  7. bzoj1003 物流运输

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...

  8. 【BZOJ1003】【ZJOI2006】物流运输

    1003: [ZJOI2006]物流运输trans Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2556  Solved: 1008[Submit] ...

  9. BZOJ 1003 物流运输 题解 【SPFA+DP】

    BZOJ 1003 物流运输 题解 Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的 ...

随机推荐

  1. vue2.0 引用qrcode.js实现获取改变二维码的样式

    vue代码 <template> <div class="qart"> <div id="qrcode" ref="qr ...

  2. SQLserver字符串分割函数

    一.按指定符号分割字符串,返回分割后的元素个数,方法很简单,就是看字符串中存在多少个分隔符号,然后再加一,就是要求的结果.CREATE function Get_StrArrayLength(  @s ...

  3. vim 查找与替换

    一.vim 查找 1. 正向查找 / 与 反向查找 ? 2. 退出查找 <Esc> 3. 跳转到下一处匹配 n ,跳转到上一处匹配 N 4. /<CR> 正向跳转到相同模式的下 ...

  4. 一份还热乎的蚂蚁面经(已拿Offer)!附答案!!

    本文来自我的知识星球的球友投稿,他在最近的校招中拿到了蚂蚁金服的实习生Offer,整体思路和面试题目由作者--泽林提供,部分答案由Hollis整理自知识星球<Hollis和他的朋友们>中「 ...

  5. 机器学习实战之SVM

    一引言: 支持向量机这部分确实很多,想要真正的去理解它,不仅仅知道理论,还要进行相关的代码编写和测试,二者想和结合,才能更好的帮助我们理解SVM这一非常优秀的分类算法 支持向量机是一种二类分类算法,假 ...

  6. Linux - 命令行 管道(Pipelines) 具体解释

    命令行 管道(Pipelines) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24249529 管道操作符" ...

  7. Android模糊效果总结

    1. 软件模糊 用软件的方法.利用cpu计算,无sdk版本号要求. 效果图: 关键模糊代码 github链接 原文 链接 译文 链接 演示样例 代码 本文地址 :http://blog.csdn.ne ...

  8. Windows 驱动入门(二)代码结构

    windows驱动程序基础.转载标明出处:http://blog.csdn.net/ikerpeng/article/details/38777641 windows驱动程序结构: 我想说的是wind ...

  9. gulp的使用方法

    ---恢复内容开始--- 什么是gulp? Gulp.js是一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务. 使用步骤: 1.全局安装gulp:    npm install - ...

  10. Runnable 和 Callable的区别

    Runnable 与 Callable的区别: (1)Callable规定的方法是call(),Runnable规定的方法是run(). (2)Callable的任务执行后可返回值,而Runnable ...