BZOJ 4326 树链剖分+二分+差分+记忆化
去年NOIP的时候我还不会树链剖分!
还是被UOJ 的数据卡了一组。
差分的思想还是很神啊!
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <ctime>
#include <cstdlib>
using namespace std;
const int Maxn=;
const int Inf=0x3f3f3f3f;
int n,m,u,v,w,cnt,tot,MaxLen,MinLen,Minw,Maxw,Ans;
int head[Maxn],dep[Maxn],siz[Maxn],father[Maxn],W[Maxn],p[Maxn],q[Maxn],dis[Maxn],Len[Maxn],c[Maxn],top[Maxn],Memory[Maxn],Root;
struct Edge{int to,next,w;}edge[Maxn<<];
inline void Get_Int(int &x)
{
x=; char ch=getchar(); int f=;
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();} x*=f;
}
inline void Put_Int(int x)
{
char ch[]; int top=;
if (x==) ch[++top]='';
while (x) ch[++top]=x%+'',x/=;
while (top) putchar(ch[top--]); putchar('\n');
}
inline int Max(int x,int y) {return x>y?x:y;}
inline int Min(int x,int y) {return x>y?y:x;}
inline void Add(int u,int v,int w)
{edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;head[u]=cnt++;}
//==============================================
void Dfs1(int u,int fa)
{
siz[u]=;
for (int i=head[u];i!=-;i=edge[i].next)
if (edge[i].to!=fa)
{
dep[edge[i].to]=dep[u]+;
father[edge[i].to]=u;
dis[edge[i].to]=dis[u]+edge[i].w;
W[edge[i].to]=edge[i].w;
Dfs1(edge[i].to,u);
siz[u]+=siz[edge[i].to];
}
}
void Dfs2(int u,int chain,int fa)
{
top[u]=chain; int k=;
for (int i=head[u];i!=-;i=edge[i].next)
if (edge[i].to!=fa && (siz[edge[i].to]>siz[k] || k==)) k=edge[i].to;
if (k==) return;
Dfs2(k,chain,u);
for (int i=head[u];i!=-;i=edge[i].next)
if (edge[i].to!=fa && k!=edge[i].to) Dfs2(edge[i].to,edge[i].to,u);
}
inline int Lca(int u,int v)
{
while (true)
{
if (top[u]==top[v]) return dep[u]>dep[v]?v:u;
if (dep[top[u]]>dep[top[v]]) u=father[top[u]]; else v=father[top[v]];
}
}
int Get(int u,int f)
{
for (int i=head[u];i!=-;i=edge[i].next)
if (f!=edge[i].to)
c[u]+=Get(edge[i].to,u);
if (c[u]==tot) MinLen=Max(MinLen,W[u]);
return c[u];
}
inline bool Check(int t)
{
MaxLen=MinLen=tot=;
memset(c,,sizeof(c));
for (int i=;i<=m;i++)
if (Len[i]>t)
{
c[p[i]]++,c[q[i]]++;
c[Lca(p[i],q[i])]-=;
MaxLen=Max(MaxLen,Len[i]);
tot++;
}
if (Memory[tot])
{
if (Memory[tot]<=t) return true;
return false;
}
Get(Root,Root);
Memory[tot]=(MaxLen-MinLen);
if (Memory[tot]<=t) return true;
return false;
}
int main()
{
srand(time());
Get_Int(n),Get_Int(m);
memset(head,-,sizeof(head)); Minw=Inf;
for (int i=;i<n;i++)
{
Get_Int(u),Get_Int(v),Get_Int(w);
Add(u,v,w),Add(v,u,w);
Minw=Min(Minw,w);
}
for (int i=;i<=m;i++) Get_Int(p[i]),Get_Int(q[i]);
Root=rand()%n+;
father[Root]=Root; dep[Root]=; dis[Root]=;
Dfs1(Root,Root);
Dfs2(Root,Root,Root);
memset(Memory,,sizeof(Memory));
for (int i=;i<=m;i++) Len[i]=dis[p[i]]+dis[q[i]]-*dis[Lca(p[i],q[i])],Maxw=Max(Maxw,Len[i]);
int l=Minw,r=Maxw;
while (l<=r)
{
int mid=(l+r)>>;
if (Check(mid)) Ans=mid,r=mid-; else l=mid+; }
Put_Int(Ans);
return ;
}
C++
BZOJ 4326 树链剖分+二分+差分+记忆化的更多相关文章
- hdu4729 树链剖分+二分
An Easy Problem for Elfness Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65535/65535 K (J ...
- NOIP 2015 BZOJ 4326 运输计划 (树链剖分+二分)
Description 公元 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n− 条双向航道,每条航道建立在两个星球之间,这 n− 条航道连通了 L 国的所有星球. 小 P 掌管一家物流公司, ...
- BZOJ_4326_[NOIP2015]_运输计划_(二分+LCA_树链剖分/Tarjan+差分)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=4326 给出一棵带有边权的树,以及一系列任务,任务是从树上的u点走到v点,代价为u到v路径上的权 ...
- BZOJ 4551[Tjoi2016&Heoi2016]树(树链剖分+二分)
Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记 ...
- BZOJ 3631 松鼠的新家 - 树链剖分 / 树上差分
传送门 分析: 树链剖分:x->y,将x到y的路径加一,并将x端点的答案-1,最后统计答案. 树上差分:x->y,x+1,y+1,lca-1,fa[lca]-1,并将x打上标记,最后统计前 ...
- 【BZOJ3307】雨天的尾巴 题解(树链剖分+树上差分)
题目链接 题目大意:给定一颗含有$n$个结点的树,每次选择两个结点$x$和$y$,对从$x$到$y$的路径上发放一带$z$类型的物品.问完成所有操作后每个结点发放最多的时哪种物品. 普通的树链剖分貌似 ...
- BZOJ 1036 && 树链剖分
还是太弱啊..各种数据结构只听过名字却没有一点概念..树链剖分也在这个范畴..今天来进一步深化一下教育改革推进全民素质提高. 性质 忘了在哪里看到的一篇blog有一句话讲得非常好,树链剖分不是一种数据 ...
- bzoj 3083 树链剖分
首先我们先将树提出一个根变成有根树,那么我们可以通过树链剖分来实现对于子树的最小值求解,那么按照当前的根和询问的点的相对位置关系我们可以将询问变成某个子树和或者除去某颗子树之后其余的和,前者直接询问区 ...
- bzoj 2243 树链剖分
2013-11-19 16:21 原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=2243 树链剖分,用线段树记录该区间的颜色段数,左右端点颜 ...
随机推荐
- 深入理解为什么Java中方法内定义的内部类可以访问方法中的局部变量
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/19996629 开篇 在我的上一篇博客 深入理解Java中为什么内部类可以访问外部类的成 ...
- struts_表单得到数据
在大家学习struts表达式语言的时候经常会遇到,从表单的提交上面得到数据, 而如何将表单的数据得到呢? 下面就介绍其中的一种方式: :以类的方式进行注入我们以login为例子 首先可以在struts ...
- ArrayList&LinkedList&Map&Arrays
Java集合框架 1:集合接口 1.1:Collection接口 Collection接口是构造集合框架的基础.它声明所有类集合都将拥有的核心方法 Boolean add(Object obj) 将o ...
- Winform中checklistbox控件的常用方法
Winform中checklistbox控件的常用方法最近用到checklistbox控件,在使用其过程中,收集了其相关的代码段1.添加项checkedListBox1.Items.Add(" ...
- Core Data
• Core Data 是 iOS SDK 里的一个很强大的框架,允许程序员 以面向对象 的方式储存和管理数据 .使用 Core Data 框架,程序员可以很轻松有效 地通过面向对象的接口 ...
- Java中的static关键字解析 转载
原文链接:http://www.cnblogs.com/dolphin0520/p/3799052.html Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到 ...
- composer安装fxp插件时候提示内存不足且没有交换空间的解决办法
The following exception is caused by a lack of memory and not having swap Check https://getcomposer. ...
- python打怪之路【第一篇】:99乘法表
需求:实现99乘法表 代码: #!/usr/bin/env python # -*- coding:utf-8 -*- #author chenjing for i in range(10): for ...
- RMAN的入门篇
一.RMAN连接数据库 1. 连接本地数据库 [oracle@oracle hotbak]$ export oracle_sid=orcl [oracle@oracle hotbak]$ rman ...
- [WebLoad] 使用WebLoad进行Web Application 性能测试的流程
1. 打开WebLOAD IDE录制或编写一个脚本文件,成功后会生成一个后缀为“.wlp”的文件. 2. 打开WebLOAD Console创建一个Load Template,创建过程当中需要添加“. ...