【bzoj2500】幸福的道路
Description
给你一棵树,每条边有边权,有两个给给的人第\(i\)天会从编号为\(i\)的点出发走这个点的树上最长距离,现在要你求一个最长的\(len\)满足\(dis_{st},dis_{st+1}...dis_{st+len-1}\)满足其中的最大值最小值之差不大于\(m\),\(dis_{i}\)表示第\(i\)天走的距离,\(st\)不一定为\(1\)
Solution
很好这题。。我一开始看错题了以为是一个弱智题(看成相邻两个差\(<=m\)了。。)
然后我没有看空间十分开心写了一个预处理rmq+双指针乱搞的玩意==
后来终于走回正道写了单调队列。。没救了真的
感觉自己对单调队列的运用还是不够熟练,所以还是搬上来加深一下印象好了
这题首先求每个点为起点的树上最长距离。。经典树形dp维护子树内最大值最小值可以\(O(n)\)求出存在\(dis\)数组里面
然后我们考虑用这样的方式求一个最长符合条件区间:我们考虑将\(n\)个数依次加进当前的区间中,记现在加到第\(i\)个数,然后在\(i-1\)这个位置结尾的最长符合条件区间的左端点为\(st\),那么将\(dis[i]\)加进来的话,如果此时区间内最大值最小值符合条件,那么更新答案,否则我们需要调整区间的左端点,将其移到一个最靠左的满足原来的\(min\)或者\(max\)不在新区间内的位置(也就是\(min\)和\(max\)中最靠前的那个的位置\(+1\)),这样我们就可以得到以每个\(i\)为右端点的最长区间,\(ans\)必定为其中的最大值
那么我们只要开两个双端队列维护当前区间内的最大值和最小值就好了,维护最大值的队列保持单调递减,维护最小值的队列保持单调递增,每次需要调整区间的时候只要找队头中较靠左的位置\(+1\)并将\(st\)调到这个位置即可
代码大概长这个样子
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const int N=1000010,TOP=20;
struct xxx{
int y,nxt;
ll dis;
}a[N];
struct Data{/*{{{*/
int which;
ll mx,smx;
Data(){}
Data(int _which,ll _mx,ll _smx){which=_which; mx=_mx; smx=_smx;}
void update(int u,ll d){
if (mx<d)
smx=mx,which=u,mx=d;
else
smx=max(smx,d);
}
}info[N];/*}}}*/
int mnq[N],mxq[N];
ll dis[N];
int h[N];
int l1,r1,l2,r2;
int n,m,tot,ans;
void add(int x,int y,ll d){a[++tot].y=y; a[tot].nxt=h[x]; h[x]=tot; a[tot].dis=d;}
void dfs(int x,ll d){
int u;
info[x]=Data(x,0,0); dis[x]=0;
for (int i=h[x];i!=-1;i=a[i].nxt){
u=a[i].y;
dfs(u,d+a[i].dis);
info[x].update(u,info[u].mx+a[i].dis);
dis[x]=max(dis[u]+a[i].dis,dis[x]);
}
}
void dfs1(int fa,int x,ll predis){
int u;
if (fa){
if (x==info[fa].which){
dis[x]=max(dis[x],info[fa].smx+predis);
info[x].update(fa,info[fa].smx+predis);
}
else{
dis[x]=max(dis[x],info[fa].mx+predis);
info[x].update(fa,info[fa].mx+predis);
}
}
for (int i=h[x];i!=-1;i=a[i].nxt){
u=a[i].y;
dfs1(x,u,a[i].dis);
}
}
void solve(){
int st=1;
l1=l2=1; r1=r2=0;
for (int i=1;i<=n;++i){
while (r1>=l1&&dis[mnq[r1]]>=dis[i]) --r1;
mnq[++r1]=i;
while (r2>=l2&&dis[mxq[r2]]<=dis[i]) --r2;
mxq[++r2]=i;
while (dis[mxq[l2]]-dis[mnq[l1]]>m){
if (mnq[l1]<mxq[l2])
st=mnq[l1]+1,++l1;
else
st=mxq[l2]+1,++l2;
}
ans=max(ans,i-st+1);
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
ll d;
int fa;
scanf("%d%d",&n,&m);
memset(h,-1,sizeof(h));
tot=0;
for (int i=2;i<=n;++i){
scanf("%d%lld",&fa,&d);
add(fa,i,d);
}
dfs(1,0);
dfs1(0,1,0);
solve();
printf("%d\n",ans);
}
【bzoj2500】幸福的道路的更多相关文章
- BZOJ2500: 幸福的道路
题解: 一道不错的题目. 树DP可以求出从每个点出发的最长链,复杂度O(n) 然后就变成找一个数列里最长的连续区间使得最大值-最小值<=m了. 成了这题:http://www.cnblogs.c ...
- bzoj2500幸福的道路 树形dp+单调队列
2500: 幸福的道路 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 434 Solved: 170[Submit][Status][Discuss ...
- [Bzoj2500]幸福的道路(树上最远点)
2500: 幸福的道路 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 474 Solved: 194[Submit][Status][Discuss ...
- bzoj2500: 幸福的道路(树形dp+单调队列)
好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...
- 【BZOJ2500】幸福的道路 树形DP+RMQ+双指针法
[BZOJ2500]幸福的道路 Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的 ...
- 【BZOJ】【2500】幸福的道路
树形DP+单调队列优化DP 好题(也是神题……玛雅我实在是太弱了TAT,真是一个250) 完全是抄的zyf的……orz我还是退OI保平安吧 第一步对于每一天求出一个从第 i 个点出发走出去的最长链的长 ...
- [BZOJ 2500] 幸福的道路
照例先贴题面(汪汪汪) 2500: 幸福的道路 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 368 Solved: 145[Submit][Sta ...
- 【bzoj2500】幸福的道路 树形dp+单调队列
Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...
- 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分
原文地址:http://www.cnblogs.com/GXZlegend/p/6825389.html 题目描述 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一 ...
- (noip模拟二十一)【BZOJ2500】幸福的道路-树形DP+单调队列
Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...
随机推荐
- Linux 安装Zookeeper<单机版>(使用Mac远程访问)
阅读本文需要先阅读安装Zookeeper<准备> 新建目录 mkdir /usr/local/zookeeper 解压 cd zookeeper压缩包所在目录 tar -xvf zooke ...
- USACO 2.4.4 Bessie Come Home 回家(最短路)
Description 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出的测试数据中,总会有且只有一只速度最快 ...
- Flip the Bits(思维)
You are given a positive integer n. Your task is to build a number m by flipping the minimum number ...
- RIGHT-BICEP测试第二次
1.Right-结果是否正确? 正确 2.B-是否所有的边界条件都是正确的? 正确 3.P-是否满足性能要求? 部分满足 4.是否满足有无括号? 无 5.数字个数是否不超过十? 只是双目运算 6.能否 ...
- c# 加载图片 正在被占用问题
问题情境:图片文件加载到pdf中,程序没有退出,再次加载该图片文件,提示被占用. 解决办法: 1.加载文件会锁定该文件,fromfile方法会导致占用内存较大,不使用该方法. FileStream f ...
- 03 JAVA IO
java.io包中定义了多个流类型来实现输入输出功能,以不同的角度进行分类: 按数据流的方向不同可以分为输入流和输出流 按处理数据单位不通可以分为字节流和字符流 按照功能不同可以分为节点流和处理流 所 ...
- 关于cnblog.com的用户体验
首先我自己目前是一个学生党,每天在博客园上就上发布一些自己做的东西以及老师布置的作业,还能在上面学习很多别人的一些好的列子,我就希望博客园能够很好地为我们这些学生服务,当我们用它时能够很好地达到我们的 ...
- 团队作业——王者光耀:team
光耀101 <光耀101>是福州大学数计学院计算机专业推出的中国首部程序猿脱发养成节目.由张栋担任发起人,刘晨瑶.畅畅担任导师. 该节目召集了你猜多少位选手,通过任务.训练.考核,让选 ...
- BOM对象属性定时器的调用
使count中的内容,自动切换 <body> <h1 id="count"></h1> </body> //获取count var ...
- 0325 实验一操作系统模拟cmd
实验一.命令解释程序的编写 专业:商软(2)班 姓名:韩麒麟 学号:201406114253 一. 实验目的 (1)掌握命令解释程序的原理: (2)掌握简单的DOS调用方法: (3)掌握C语言编程 ...