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

HINT

数据范围:
50%的数据N<=1000
80%的数据N<=100000
100%的数据N<=1000000

题解:

其实这题很水……全场切掉,但是自己很少写单调队列(几乎没写过),所以调了很久最后发现了数个傻逼错……搞了很久才对……

首先这题是树形DP+单调队列二合一,前半部分直接DP,设$F[i]$表示以$i$为根的子树里最长的距离,$G[i]$表示从$i$向上走到一个祖先再向下的最大值,直接两次dfs处理(转移的时候要记录一个次大值)。那么最大的幸福值就是$max(F[i],G[i])$;

后半部分注意到可选的区间是连续的,所以左右端点必定严格从左向右移动,所以可以用单调队列来维护,开两个单调队列维护区间最大最小值,记录当前区间大小即可(我也不知道我为什么能写出那么多傻逼错)

代码:

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
struct edge{
int v,w,next;
}a[];
int n,m,x,w,tot=,ans=,tmp=,head[],num[],f[],ff[],g[];
//queue<int>ql,qr;
int ql[],qr[],l1=,l2=,r1=-,r2=-;
void add(int u,int v,int w){
a[++tot].v=v;
a[tot].w=w;
a[tot].next=head[u];
head[u]=tot;
}
void dfs1(int u){
f[u]=ff[u]=;
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v,w=a[tmp].w;
dfs1(v);
if(f[v]+w>f[u]){
ff[u]=f[u];
f[u]=f[v]+w;
}else if(f[v]+w>ff[u]){
ff[u]=f[v]+w;
}
}
}
void dfs2(int u){
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v,w=a[tmp].w;
g[v]=g[u]+w;
if(f[v]+w==f[u])g[v]=max(g[v],ff[u]+w);
else g[v]=max(g[v],f[u]+w);
dfs2(v);
}
}
int main(){
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d%d",&x,&w);
add(x,i,w);
}
dfs1();
dfs2();
for(int i=;i<=n;i++)num[i]=max(f[i],g[i]);
for(int i=;i<=n;i++){
while(l1<=r1&&num[i]<=num[ql[r1]])r1--;
ql[++r1]=i;
while(l2<=r2&&num[i]>=num[qr[r2]])r2--;
qr[++r2]=i;
while(num[qr[l2]]-num[ql[l1]]>m){
tmp=ql[l1]<qr[l2]?ql[l1++]+:qr[l2++]+;
}
ans=max(ans,i-tmp+);
}
printf("%d",ans);
return ;
}

最新文章

  1. WPF显示Html
  2. NOIp 2013 #2 花匠 Label:爆0的Water
  3. 2模02day1题解
  4. php大力力 [013节]mySQL数据库乱码问题我还没解决
  5. FindResource函数错误代码:1813-找不到映像文件中指定的资源类型 与LoadResource函数错误代码:1812-指定的映像文件不包含资源区域
  6. BZOJ3132: 上帝造题的七分钟
  7. java socket报文通信(三)java对象和xml格式文件的相互转换
  8. MFC自绘(17篇)
  9. 使用vscode对c进行调试
  10. Linux sftp 另外一台机器时,出现:receive message is too long
  11. 洛谷 [P3033] 牛的障碍
  12. PyQt5 api 帮助文档
  13. pyCharm-激活码(2018)
  14. python写入txt文件时的覆盖和追加
  15. Django基础介绍
  16. Ansible Tower系列 二(安装 Tower)【转】
  17. 2018/04/17 每日一个Linux命令 之 tar
  18. [转]一个CMake编译问题的解决过程
  19. 学习微信小程序及知识占及v-if与v-show差别
  20. [置顶] 如何用PYTHON代码写出音乐

热门文章

  1. TCP基本概念
  2. C++利用函数模板得到数组的长度
  3. BZOJ 1834: [ZJOI2010]network 网络扩容 最小费用流_最大流_残量网络
  4. 路飞学城Python-Day32【小结】
  5. Codeforces 675B Restoring Painting
  6. CF1042F Leaf Sets (贪心+树上构造)
  7. 模板 NTT 快速数论变换
  8. webpack配置相关的页面异常
  9. 小学生都能学会的python(字典{ })
  10. 【codeforces 812B】Sagheer, the Hausmeister