【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发现可以用树来描绘这个草图. ...
随机推荐
- YAML 基础
YAML 基础 简介 对象 数组 常量 引用 1. 简介 YAML 是专门用来写配置文件的语言,非常简洁和强大! 它的基本语法规则有: 大小写敏感: 使用缩进表示层级关系: 缩进时不允许使用 Tab ...
- Mysql 单表主从同步
先配主从同步,后将主库表老数据传输到从库 说明:api-server的数据库为主,其他harbor为从 1.master 配置文件更改 [mysqld] log-bin = mysql-bin ser ...
- K-means + PCA + T-SNE 实现高维数据的聚类与可视化
使用matlab完成高维数据的聚类与可视化 [idx,Centers]=kmeans(qy,) [COEFF,SCORE,latent] = pca(qy); SCORE = SCORE(:,:); ...
- 与面试官谈笑风生 | Python面向对象之访问控制
Python从设计之初就是一门面向对象的语言,面向对象思想的第一个要素就是封装.所谓封装,通俗的讲就是类中的属性和方法,分为公有和私有,公有可以被外界访问,私有不能被外界访问,这就是封装中最关键的概念 ...
- 04慕课网《进击Node.js基础(一)》HTTP讲解
HTTP:通信协议 流程概述: http客户端发起请求,创建端口默认8080 http服务器在端口监听客户端请求 http服务器向客户端返回状态和内容 稍微详细解析: 1.域名解析:浏览器搜素自身的D ...
- python 二维矩阵及转byte知识点
1.注意python中的数组和list形式混合: 数组在numpy里面: 2.二维数组这样定义可以修改固定位置的值: rawDataArray_temp = [([0]*nIRImageWidth)f ...
- ios framework 使用图片资源
framework 的制作工程见:http://www.cocoachina.com/ios/20141126/10322.html: 遇到问题: 由于自己的framework 要使用图片资源,最后找 ...
- CDOJ ABCDE dp(前缀和优化)
题目链接: http://acm.uestc.edu.cn/#/problem/show/1307 ABCDE Time Limit: 1000/1000MS (Java/Others)Memory ...
- sql主表分页查询关联子表取任意一条高效方案
有个业务场景,主表中一条数据,在子表中有多条详情数据.对数据进行展示的时候,产品希望随意拿一条子表的数据关联展示出来,用了很多方案,但是都不够好. sql查询取子表任意一条,多个字段的方案 最终找到一 ...
- C语言之goto浅析
1. 读代码时遇了的疑惑点: static int do_bind(const char *host, int port, int protocol, int *family) { int fd; ...