二分+树剖+差分

之前的做法naive,莫名其妙的wa,明明uoj95分

看到最小最大上二分,树上路径问题直接剖,然后问题就转化成了一个判定问题,每次二分出最长路径长度,问能不能达到。那么我们就把所有长度大于二分出的d的路径拉出来,求出他们公共路径的最大长度,看减去能不能满足。那么现在的问题就转化成了求路径的交。我们可以利用bzoj4390的树上差分的方法解决,我们先把边转化为点,即每条边等价于他连接的深度较深的点,那么我们利用树上差分标记路径上的边,把路径上的边标记+1,这个我们只要在u,v,+1,lca,-2就行了,然后我们求一个前缀和,看子树权值是否等于路径数量就行了。

树上差分是一种重要的思想,大概有几种方法,

1.像这道题和bzoj4390,可以标记路径上的点/边

2.像noip2016day1t2,雨天的尾巴,利用树剖重链是一段连续的区间且最多只有log条重链,我们可以log时间修改路径的信息,这和上面的差分是不一样的,因为如果按上面的方法差分那么可能会把这条路径上的信息带到其他的点,而树剖保证dfs序连续,所以每条重链差分一下,那么就不会带入到其他点,这样一共会打logn个标记

原先是像魔法森林那样把边权转化为点权,时间爆炸

#include<bits/stdc++.h>
using namespace std;
const int N = ;
struct edge {
int nxt, to, w;
} e[N << ];
struct path {
int u, v, w;
bool friend operator < (path a, path b) { return a.w > b.w; }
} a[N];
namespace IO
{
const int Maxlen = N * ;
char buf[Maxlen], *C = buf;
int Len;
inline void read_in()
{
Len = fread(C, , Maxlen, stdin);
buf[Len] = '\0';
}
inline void fread(int &x)
{
x = ;
int f = ;
while (*C < '' || '' < *C) { if(*C == '-') f = -; ++C; }
while ('' <= *C && *C <= '') x = (x << ) + (x << ) + *C - '', ++C;
x *= f;
}
inline void read(int &x)
{
x = ;
int f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = (x << ) + (x << ) + c - ''; c = getchar(); }
x *= f;
}
inline void read(long long &x)
{
x = ;
long long f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = (x << 1ll) + (x << 3ll) + c - ''; c = getchar(); }
x *= f;
}
} using namespace IO;
int n, m, cnt = , tot, lim;
int tree[N], mark[N], mir[N], head[N], dis[N], size[N], son[N], dep[N], fa[N], top[N], Lca[N], w[N], in[N], out[N];
void link(int u, int v, int w)
{
e[++cnt].nxt = head[u];
head[u] = cnt;
e[cnt].to = v;
e[cnt].w = w;
}
void dfs(int u, int last)
{
size[u] = ;
dis[u] = dis[last] + w[u];
for(int i = head[u]; i; i = e[i].nxt) if(e[i].to != last)
{
dep[e[i].to] = dep[u] + ;
fa[e[i].to] = u;
w[e[i].to] = e[i].w;
dfs(e[i].to, u);
size[u] += size[e[i].to];
if(size[e[i].to] > size[son[u]]) son[u] = e[i].to;
}
}
void dfs(int u, int acs, int last)
{
in[u] = ++tot;
mir[tot] = u;
top[u] = acs;
if(son[u]) dfs(son[u], acs, u);
for(int i = head[u]; i; i = e[i].nxt) if(e[i].to != last && e[i].to != son[u]) dfs(e[i].to, e[i].to, u);
out[u] = tot;
}
int lca(int u, int v)
{
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]]) swap(u, v);
u = fa[top[u]];
}
return dep[u] < dep[v] ? u : v;
}
int Dis(int u, int v)
{
int x = lca(u, v);
return dis[u] + dis[v] - * dis[x];
}
void update(int x, int d)
{
for(; x <= n; x += x & (-x)) tree[x] += d;
}
int query(int x)
{
int ret = ;
for(; x; x -= x & (-x)) ret += tree[x];
return ret;
}
bool check(int d)
{
memset(mark, , sizeof(mark));
int cou = , mx = ;
for(int i = ; i <= m; ++i)
{
if(a[i].w <= d) break;
++cou;
mark[in[Lca[i]]] -= ;
++mark[in[a[i].u]];
++mark[in[a[i].v]];
}
for(int i = ; i <= n; ++i) mark[i] += mark[i - ];
for(int i = ; i <= n; ++i)
{
int tmp = mark[out[i]] - mark[in[i] - ];
if(tmp == cou) mx = max(mx, w[i]);
}
return a[].w - mx <= d;
}
int main()
{
read_in();
fread(n);
fread(m);
for(int i = ; i < n; ++i)
{
int u, v, w;
fread(u);
fread(v);
fread(w);
link(u, v, w);
link(v, u, w);
}
dfs(, );
dfs(, , );
for(int i = ; i <= m; ++i)
{
fread(a[i].u);
fread(a[i].v);
a[i].w = Dis(a[i].u, a[i].v);
lim = max(lim, a[i].w);
}
sort(a + , a + m + );
for(int i = ; i <= m; ++i) Lca[i] = lca(a[i].u, a[i].v);
int l = -, r = lim + , ans = ;
while(r - l > )
{
int mid = (l + r) >> ;
if(check(mid)) r = ans = mid;
else l = mid;
}
printf("%d\n", ans);
return ;
}

bzoj4326的更多相关文章

  1. [BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划

    [BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划 试题描述 公元 2044 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n− ...

  2. 【bzoj4326】[NOIP2015]运输计划

    题目描述 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家物流公司, 该 ...

  3. NOIP2015 运输计划(bzoj4326)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 886  Solved: 574[Submit][Status] ...

  4. [bzoj4326][NOIP2015]运输计划

    Description 公元2044年,人类进入了宇宙纪元. 国有个星球,还有条双向航道,每条航道建立在两个星球之间,这条航道连通了国的所有星球. 小掌管一家物流公司,该公司有很多个运输计划,每个运输 ...

  5. 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 703  Solved: 461[Submit][Status] ...

  6. bzoj4326 运输计划

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MB Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n ...

  7. NOIP2015 D2T3 洛谷2680 BZOJ4326 运输计划 解题报告

    前言:个人认为这是历年NOIP中比较简单的最后一题了,因此将自己的思路与大家分享. 题目大意: 给一棵无根树,给出m条路径.允许将树上的一条边的权值改为0.求m条路径长度最大值的最小值.n,m< ...

  8. bzoj4326 树链剖分 + 线段树 // 二分 lca + 树上差分

    https://www.lydsy.com/JudgeOnline/problem.php?id=4326 题意:N个点的树上给M条树链,问去掉一条边的权值之后所有树链长度和的最大值最小是多少. 首先 ...

  9. BZOJ4326或洛谷2680 运输计划

    BZOJ原题链接 洛谷原题链接 用\(LCA\)初始化出所有运输计划的原始时间,因为答案有单调性,所以二分答案,然后考虑检验答案. 很容易想到将所有超出当前二分的答案的运输计划所经过的路径标记,在这些 ...

  10. 2018.09.26 bzoj4326: NOIP2015 运输计划(二分+树上差分)

    传送门 简单树上操作. 先转边权为点权. 显然所有的询问操作对应的路径会有一些交点,那么我们可以直接二分答案,对于所有大于二分值的询问用树上差分维护,最后dfs一遍每个点被覆盖了几次,当前情况合法当且 ...

随机推荐

  1. 生物遗传学 整理人PYJ (恋_紫花地丁)

    生物遗传学整理人PYJ (恋_紫花地丁) 高中生物唯一需要数学知识的就是遗传学的概率计算了.这里对简单的遗传学规律做一些总结. 目录: 1.      孟德尔第一定律(分离定律): 2.      孟 ...

  2. 【PD】PowerDesigner生成数据字典

    1.首先说明我使用的环境 --------------------------------第一种:不按模板导出导出数据字典----------------------------- 2.打开PDM模型 ...

  3. msp430项目编程

    msp430中项目---LED数码管显示 1.数码管介绍 2.代码(直接使用引脚驱动) 3.代码(使用译码器驱动) 4.项目总结 msp430项目编程 msp430入门学习

  4. php 之 日志系统seaslog安装

    php 之 日志系统seaslog 特点: 1.高性能(使用C语言编写的). 2.无需配置. 3.功能完善.使用简单. 安装: 打开php的扩展官网:https://pecl.php.net/. 然后 ...

  5. Python()-类命名空间和对象/实例命名空间

    类命名空间和对象/实例命名空间: 创建类, 就会创建一个类的名称空间, 空间:存储类的属性 属性: 静态属性:直接定义在类下面 & 和类名关联 的变量 对象属性:在类内和self关联 & ...

  6. 由八数码问题引入。对BFS有更深考虑

    12号到今天共研究八数码问题poj1077,首先用的是普通BFS,遇到很多问题,开始用一个二级指针作为结构成员,知道了二级指针与二维数值名的不同!http://write.blog.csdn.net/ ...

  7. BZOJ 3884 拓展欧拉定理

    3884: 上帝与集合的正确用法 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 4142  Solved: 1907[Submit][Status][D ...

  8. HDU 4193 Non-negative Partial Sums【单调队列】

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4193 题意: 给定序列,可以把后面的连续的部分移到最前面来,问多少种移法使得最终得到的序列的前i项和 ...

  9. [RxJS] Implement RxJS `mergeMap` through inner Observables to Subscribe and Pass Values Through

    Understanding sources and subscribers makes it much easier to understand what's going on with mergeM ...

  10. Spark SQL 源代码分析之Physical Plan 到 RDD的详细实现

    /** Spark SQL源代码分析系列文章*/ 接上一篇文章Spark SQL Catalyst源代码分析之Physical Plan.本文将介绍Physical Plan的toRDD的详细实现细节 ...