【BZOJ2500】幸福的道路

Description

小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光.
他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图.
他们不愿枯燥的每天从同一个地方开始他们的锻炼,所以他们准备给起点标号后顺序地从每个起点开始(第一天从起点一开始,第二天从起点二开始……). 而且他们给每条道路定上一个幸福的值.很显然他们每次出发都想走幸福值和最长的路线(即从起点到树上的某一点路径中最长的一条).
他们不愿再经历之前的大起大落,所以决定连续几天的幸福值波动不能超过M(即一段连续的区间并且区间的最大值最小值之差不超过M).他们想知道要是这样的话他们最多能连续锻炼多少天(hint:不一定从第一天一直开始连续锻炼)?
现在,他们把这个艰巨的任务交给你了!

Input

第一行包含两个整数N, M(M<=10^9).
第二至第N行,每行两个数字Fi , Di, 第i行表示第i个节点的父亲是Fi,且道路的幸福值是Di.

Output

最长的连续锻炼天数

Sample Input

3 2
1 1
1 3

Sample Output

3
数据范围:
50%的数据N<=1000
80%的数据N<=100 000
100%的数据N<=1000 000

题解:这题显然可以被分成两个子任务

1.求树上距离点i最远的点到i的距离

方法:维护每个点子树中到这个点距离的最大值和次大值,然后搞一搞~

2.求最长的一段区间,使得区间中最大值和最小值的差≤M

方法:先用RMQ求出区间最大值最小值,然后上双指针法

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=1000010;
int n,m,cnt,l,r,ans;
int fa[maxn],to[maxn<<1],next[maxn<<1],head[maxn];
int d1[maxn],d2[maxn],q[maxn],from[maxn];
int Log[maxn],dm[maxn][20],dn[maxn][20];
void updata(int x,int tmp)
{
if(d1[x]<tmp) d2[x]=d1[x],d1[x]=tmp;
else d2[x]=max(d2[x],tmp);
}
void dfs1(int x)
{
int i,tmp;
q[++q[0]]=x;
for(i=head[x];i!=-1;i=next[i])
dfs1(to[i]),updata(x,d1[to[i]]+from[to[i]]);
}
void add(int a,int b)
{
to[cnt]=b;
next[cnt]=head[a];
head[a]=cnt++;
}
int gm(int a,int b)
{
int k=Log[b-a+1];
return max(dm[a][k],dm[b-(1<<k)+1][k]);
}
int gn(int a,int b)
{
int k=Log[b-a+1];
return min(dn[a][k],dn[b-(1<<k)+1][k]);
}
int main()
{
scanf("%d%d",&n,&m);
int i,j,a,b,c;
memset(head,-1,sizeof(head));
for(i=2;i<=n;i++)
{
scanf("%d%d",&fa[i],&from[i]);
add(fa[i],i);
}
dfs1(1);
for(i=2;i<=n;i++)
{
if(d1[fa[q[i]]]==d1[q[i]]+from[q[i]]) updata(q[i],d2[fa[q[i]]]+from[q[i]]);
else updata(q[i],d1[fa[q[i]]]+from[q[i]]);
}
for(i=1;i<=n;i++) dm[i][0]=dn[i][0]=d1[i];
for(i=2;i<=n;i++) Log[i]=Log[i>>1]+1;
for(j=1;(1<<j)<=n;j++)
{
for(i=1;i+(1<<j)-1<=n;i++)
{
dm[i][j]=max(dm[i][j-1],dm[i+(1<<j-1)][j-1]);
dn[i][j]=min(dn[i][j-1],dn[i+(1<<j-1)][j-1]);
}
}
int h=1;
ans=-1;
for(i=1;i<=n;i++)
{
while(gm(h,i)-gn(h,i)>m) h++;
ans=max(ans,i-h+1);
}
printf("%d",ans);
return 0;
}

【BZOJ2500】幸福的道路 树形DP+RMQ+双指针法的更多相关文章

  1. bzoj2500幸福的道路 树形dp+单调队列

    2500: 幸福的道路 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 434  Solved: 170[Submit][Status][Discuss ...

  2. 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分

    原文地址:http://www.cnblogs.com/GXZlegend/p/6825389.html 题目描述 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一 ...

  3. (noip模拟二十一)【BZOJ2500】幸福的道路-树形DP+单调队列

    Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...

  4. 【bzoj2500】幸福的道路 树形dp+单调队列

    Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...

  5. [BZOJ 2500]幸福的道路 树形dp+单调队列+二分答案

    考试的时候打了个树链剖分,而且还审错题了,以为是每天找所有点的最长路,原来是每天起点的树上最长路径再搞事情.. 先用dfs处理出来每个节点以他为根的子树的最长链和次长链.(后面会用到) 然后用类似dp ...

  6. hdu 4123 树形DP+RMQ

    http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...

  7. 重建道路 树形DP

    重建道路 树形DP 给一棵树,问最少断多少边使得这棵树树最终只有\(p​\)个节点 设计dp状态\(f[u][i][j]\)表示节点\(u\),到第\(i\)个儿子,使\(j\)个节点分离,但是不分离 ...

  8. bzoj2500: 幸福的道路(树形dp+单调队列)

    好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...

  9. BZOJ2500: 幸福的道路

    题解: 一道不错的题目. 树DP可以求出从每个点出发的最长链,复杂度O(n) 然后就变成找一个数列里最长的连续区间使得最大值-最小值<=m了. 成了这题:http://www.cnblogs.c ...

随机推荐

  1. Python3内置字符串方法详解

    官网文档地址:https://docs.python.org/3/library/stdtypes.html#string-methods基于 Python 3.X 版本 str.capitalize ...

  2. selenium 实现浏览器 前进和后退

    #coding=utf-8from selenium import webdriver driver = webdriver.Chrome()driver.get("https://www. ...

  3. SQLSERVER中的timestamp 和 C#中的byte[] 转换

    项目中由于需求设计,数据库中需要一个timestamp时间戳类型的字段来作为区别数据添加和修改的标识.由于timestamp在SQL SERVER 2005数据库中,不可为空的timestamp类型在 ...

  4. COM方式实现C++调用C#代码的一些总结

    首先这个测试没成功,只在本机上可行,在不同机器上测试失败.可能是GUID不对或者没注册成功. 既然已经花了一上午时间去研究,还是总结一下 1.网上说要创建一个snk证书,但不创建也可以.只不过不能放入 ...

  5. Atitit. 软件GUI按钮与仪表盘--web服务器区--获取apache配置文件路径 linux and apache的启动、停止、重启

    Atitit.   软件GUI按钮与仪表盘--web服务器区--获取apache配置文件路径 linux and apache的启动.停止.重启 可以通过"netstat -anp" ...

  6. shell获取用户输入

    主题: 再学shell之获取用户输入echo -n(不换行)和read命令-p(提示语句) -n(字符个数) -t(等待时间) -s(不回显) 和“读文件”深入学习 1.基本读取read命令接收标准输 ...

  7. 用wget做站点镜像

    用wget做站点镜像 -- :: 分类: LINUX # wget -r -p -np -k http://xxx.edu.cn -r 表示递归下载,会下载所有的链接,不过要注意的是,不要单独使用这个 ...

  8. js 树菜单 ztree

    http://www.ztree.me/v3/api.php 官网 api js /** <div id="menuContent" class="menuCont ...

  9. Extjs,实现树形结构的总结

    工作总结,用extjs.mybatis.springMVC实现树形显示班级 前台extjs实现树形代码如下: xtype : 'combotree', fieldLabel : '部门名称', nam ...

  10. C语言 · 大数加法

    算法提高 大数加法   时间限制:1.0s   内存限制:256.0MB      问题描述 输入两个正整数a,b,输出a+b的值. 输入格式 两行,第一行a,第二行b.a和b的长度均小于1000位. ...