Portal -->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】幸福的道路的更多相关文章

  1. BZOJ2500: 幸福的道路

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

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

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

  3. [Bzoj2500]幸福的道路(树上最远点)

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

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

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

  5. 【BZOJ2500】幸福的道路 树形DP+RMQ+双指针法

    [BZOJ2500]幸福的道路 Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的 ...

  6. 【BZOJ】【2500】幸福的道路

    树形DP+单调队列优化DP 好题(也是神题……玛雅我实在是太弱了TAT,真是一个250) 完全是抄的zyf的……orz我还是退OI保平安吧 第一步对于每一天求出一个从第 i 个点出发走出去的最长链的长 ...

  7. [BZOJ 2500] 幸福的道路

    照例先贴题面(汪汪汪) 2500: 幸福的道路 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 368  Solved: 145[Submit][Sta ...

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

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

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

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

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

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

随机推荐

  1. jenkins升级为2.134

    由于前面装的jenkins版本为2.130版本,昨天(2018.7.26)发现了两个jenkins的漏洞,影响范围为:Jenkins weekly 2.132 以及更早的版本.Jenkins LTS ...

  2. P,V操作及同步互斥实例

    无论是计算机考研.计算机软件水平考试.计算机操作系统期末考试还是其他计算机岗位考试,P.V原语操作都是一个常考点.下面笔者总结了关于P.V操作的一些知识. 信号量是最早出现的用来解决进程同步与互斥问题 ...

  3. libCurl 初步认识 - cur easy

    cur easy接口简洁明了,主接口4个,辅接口5个. 主接口 初始化 + 配参数 + 执行 + 销毁 初始化 CURL* curl_easy_init() 获得CURL句柄,返回值需要判空. 配参数 ...

  4. PytorchZerotoAll学习笔记(四)--线性回归

    线性回归 # 导入 torch.torch.autograd的Variable模块import torch from torch.autograd import Variable # 生成需要回归需要 ...

  5. python序列成员资格

    可以用做登录操作,判断用户名密码是否正确! 代码示例: database = [ ['], ['], ['], ['] ] username = input("UserName: " ...

  6. Python Requests库入门——应用实例-京东商品页面爬取+模拟浏览器爬取信息

    京东商品页面爬取 选择了一款荣耀手机的页面(给华为打广告了,荣耀play真心不错) import requests url = "https://item.jd.com/7479912.ht ...

  7. 通俗理解Hilbert希尔伯特空间

    作者:qang pan 链接:https://www.zhihu.com/question/19967778/answer/28403912 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权, ...

  8. ASP.NET MVC5 学习系列之模型绑定

    一.理解 Model Binding Model Binding(模型绑定) 是 HTTP 请求和 Action 方法之间的桥梁,它根据 Action 方法中的 Model 类型创建 .NET 对象, ...

  9. 总结在Visual Studio Code创建Node.js+Express+handlebars项目

    一.安装node.js环境. Node.js安装包及源码下载地址为:https://nodejs.org/en/download/ 32 位安装包下载地址 : https://nodejs.org/d ...

  10. HDU 1121 Complete the Sequence 差分

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1121 Complete the Sequence Time Limit: 3000/1000 MS ...