**开始天真的我以为这道题和运输计划是一样的套路。于是写了一发,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. Vue DOM事件

    本文参考自:https://mp.weixin.qq.com/s?src=3&timestamp=1527154113&ver=1&signature=tWGeTa86gyK* ...

  2. javascript的window.open()具体解释

    通过button打开一个新窗体.并在新窗体的状态栏中显示当前年份. 1)在主窗体中应用下面代码加入一个用于打开一个新窗体的button: <body> <script type=&q ...

  3. 将Cocos2d-x游戏打包成Android应用程序

    1. 打开Eclipse(已经装好CDT.ADT和NDK),导入cocos2d-x的Android项目. 2. 导入后java的源码会出现编译错误,打开cocos2d-x引擎的根文件夹\cocos2d ...

  4. 3、C++新的关键字

        C++ 添加了一些全新的关键字. 1.new     new 来进行动态内存的分配,而delect 则是进行内存的释放, 申请的方式: 变量申请: int *p = new int; // 申 ...

  5. sql数据库log自动增长被取消

    原因分析:数据库可分配空间为0 解决方法:增加数据库初始大小

  6. 自己定义ProgressDialog载入图片

    使用系统载入框 mDialog = new ProgressDialog(this); mDialog.setCancelable(true);//能否够被取消 mDialog.setMessage( ...

  7. SpringBoot启动流程分析(二):SpringApplication的run方法

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  8. VS中单元测试用法

    using System; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace UnitTestProject1 { [Test ...

  9. js嵌套Struts2标签

    在页面中如果想要在js代码块里面获取到某些值,而这些值是通过Struts的标签取到的, 如: var operatorType = '<s:property value="#sessi ...

  10. hibernate3中session.get()与session.load()两个方法的区别?

    1.发送sql的时机不同:load采用延迟加载技术,只有当真正去使用所查处的对象时,才会发送sql:get采用的是立即检索技术,当执行到get方法是就会立即发送sql. 2.返回的对象不同:load返 ...