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 树链剖分,用线段树记录该区间的颜色段数,左右端点颜 ...
随机推荐
- Unity的旋转-四元数,欧拉角用法简介
当初弄不明白旋转..居然找不到资料四元数应该用轴角相乘...后来自己摸明白了 通过两种旋转的配合,可以告别世界空间和本地空间矩阵转换了,大大提升效率. 每个轴相乘即可,可以任意轴,无限乘.无万向节锁问 ...
- [书]WALL·E、龙与地下铁、中国美丽的故事、故事新编、四十自述、书虫、人工智能、大话数据结构
下午有时间,逛了逛了书城,看到了一些书.在这里总结一些自己的感受. 一.<龙与地下铁> 这本书是我首先看到的,就在靠前的新书区.是小说,我没看里面的内容,但是被书封皮的宣传文案 ...
- 配置eclipse使能打开当前文件所在目录
配置方法如下:Run -> External Tools -> External Tools Configurations...右键Program,new 在右边的界面中: Locatio ...
- cocos2dx 动画显示异常
最近遇到一个问题 好多cocostudio导出的动画 显示都会有异常 很明显的融合方式 把混合方式里面的 src 改成one dst 改成 one-src alpha 解决 后面附上同行的文章 浅显易 ...
- Flex 学习笔记 ComboBox内容框宽度
如何设置ComboBox下拉选项框的宽度呢 左边下拉框发现字符太长了 属性里也找不到相关宽度可以设置,解决如下 <!--添加open事件 打开下拉选项框时设置--> <s:Com ...
- ElasticSearch学习问题记录——nested查询不到数据
通过代码创建了索引名称为demoindex,索引类型为school,以下是索引类型的数据映射结构: { "state": "open", "setti ...
- JMS消息中间件系列[ActiveMQ](一)
版本5.13.3的特性: 1.Supports a variety of Cross Language Clients and Protocols from Java, C, C++, C#, Rub ...
- python 正则表达式总结
一.匹配元字符 使用元字符可以简便操作,写正则表达式时更方便 常用元字符: . 它匹配除了换行字符外的任何字符,在 alternate 模式(re.DOTALL)下它甚至可以匹配换行 ^ 匹配行首. ...
- MTF(Move-to-front transform)数据转换
1.什么是MTF MTF(move-to-front)是一种数据编码方式,用于提高数据压缩技术效果. 在数据压缩算法中,MTF可以作为一个额外的步骤.也就是说 ,可以先进行MTF编码,在进行数据压缩. ...
- js获取url参数值,js获取其他页面传递而来的值
index.htm?参数1=数值1&参数2=数值2&参数3=数据3&参数4=数值4&...... 静态html文件js读取url参数 根据获取html的参数值控制htm ...