照例先贴题面(汪汪汪)

2500: 幸福的道路

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 368  Solved: 145
[Submit][Status][Discuss]

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
对于这道题来说我们可以考虑预处理出每个结点的最长路径长然后乱搞
对于预处理我在考场上写了个对于每个结点DFS一遍求最长,然后$std::set$维护最大最小值,总时间复杂度瓶颈为预处理$O(n^2)$
实际上我们可以先求这个树的直径结点,然后从分别从两个直径结点进行DFS并取最大值来预处理出最长路径长。直径为树中最长的一条路径。这一过程需要固定的4遍DFS所以时间复杂度$O(n)$
考场上鬼使神差地脑抽认为求直径会有反例
然后就是求最长连续区间的问题,我的策略是建立左右两个哨兵,采用一直让右哨兵前进并更新最大值直至最大最小值超过限制条件,超限之后采用不断删除左哨兵的值并前进直至符合条件的贪心策略。因为$std::set$的插入与查询是$O(logn)$,每个点肯定要插入/删除一次所以贪心过程时间复杂度$O(nlogn)$,总时间复杂度$O(nlogn)$
这里其实还可以使用单调队列,但是因为单调队列要固定区间长度所以只能采取二分长度策略,总时间复杂度也是$O(nlogn)$。
然后袋马时间:
 #include <set>
#include <cstdio>
#include <algorithm> const int MAXE=;
const int MAXV=; struct Edge{
int from;
int to;
int dis;
Edge* next;
};
Edge E[MAXE];
Edge* head[MAXV];
Edge* top=E; int n;
int m;
int lg1;
int lg2;
int dis[MAXV]; void Initialize();
std::pair<int,int> DFS(int,int,int);
void DFSA(int,int,int);
void Insert(int,int,int);
int Sweep(); int main(){
Initialize();
lg1=DFS(,,).second;
lg2=DFS(lg1,,).second;
DFSA(lg1,,);
DFSA(lg2,,);
printf("%d\n",Sweep());
// printf("%d %d\n",lg1,lg2);
return ;
} std::pair<int,int> DFS(int root,int prt,int dis){
std::pair<int,int> ans(dis,root);
for(Edge* i=head[root];i!=NULL;i=i->next){
if(i->to==prt)
continue;
ans=std::max(ans,DFS(i->to,root,dis+i->dis));
}
return ans;
} void DFSA(int root,int prt,int dis){
::dis[root]=std::max(::dis[root],dis);
for(Edge* i=head[root];i!=NULL;i=i->next){
if(i->to==prt)
continue;
DFSA(i->to,root,dis+i->dis);
}
} int Sweep(){
int l=,r=,ans=;
// std::priority_queue<int,std::vector<int>,std::less<int>> qmax;
// std::priority_queue<int,std::vector<int>,std::greater<int>> qmin;
std::multiset<int> s;
while(r<=n){
// printf("%d\n",r);
s.insert(dis[r]);
while(*(--s.end())-*s.begin()>m){
s.erase(s.find(dis[l]));
++l;
}
ans=std::max(ans,int(s.size()));
++r;
}
return ans;
} void Initialize(){
int a,b;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d%d",&a,&b);
Insert(a,i,b);
Insert(i,a,b);
}
} inline void Insert(int from,int to,int dis){
top->to=to;
top->dis=dis;
top->from=from;
top->next=head[from];
head[from]=top;
top++;
}

Backup

以及图包时间

[BZOJ 2500] 幸福的道路的更多相关文章

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

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

  2. ●BZOJ 2500 幸福的道路

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2500 题解: DFS,单调队列 首先有一个结论,距离树上某一个点最远的点一定是树的直径的一个 ...

  3. bzoj 2500 幸福的道路 树上直径+set

    首先明确:树上任意一点的最长路径一定是直径的某一端点. 所以先找出直径,求出最长路径,然后再求波动值<=m的最长区间 #include<cstdio> #include<cst ...

  4. BZOJ 2500 幸福的道路(race) 树上直径+平衡树

    structHeal { priority_queue<int> real; priority_queue<int> stack; void push(int x){ real ...

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

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

  6. BZOJ2500: 幸福的道路

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

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

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

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

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

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

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

随机推荐

  1. springMVC 配置和使用

    springMVC相对于Struts2学习难度较为简单,并且更加灵活轻便. 第一步:导入jar包 spring.jar.spring-webmvc.jar.commons-logging.jar.sp ...

  2. WPF MVVM 架构 Step By Step(4)(添加bindings - 完全去掉后台代码)

    之前的改进已经挺棒的,但是我们现在知道了后台代码的问题,那是否可能把后台代码全部去除呢?这时候就该WPF binding 和 commands 来做的事情了. WPF就是以超吊的binding,com ...

  3. EF编辑

    //修改推荐的信息 var productRe = db.Shop_ProductRecommends.Single(item => item.Id == model.Id); productR ...

  4. noip模拟 市长选举

    题目描述 利贝尔王国的卢安市因为前段时间的市长被捕事件,导致没有市长管理城市.他们需要一个新的市长. 竞选的人有两位.一位是诺曼,因支持旅游业而受到支持者的拥护.一位是波尔多斯,代表的是卢安的传统行业 ...

  5. none 和 host 网络的适用场景 - 每天5分钟玩转 Docker 容器技术(31)

    本章开始讨论 Docker 网络. 我们会首先学习 Docker 提供的几种原生网络,以及如何创建自定义网络.然后探讨容器之间如何通信,以及容器与外界如何交互. Docker 网络从覆盖范围可分为单个 ...

  6. 数据结构与算法(c++)——查找二叉树与中序遍历

    查找树ADT--查找二叉树 定义:对于树中的每个节点X,它的左子树中的所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项. 现在给出字段和方法定义(BinarySearchTree.h) # ...

  7. Intellij IDEA查看方法的调用栈

    在IDEA中,先双击选定要查看的方法,使用快捷键Ctrl+Alt+h,在右侧就会显示该方法的详细信息,再双击右侧的方法,就定位到方法的代码区.如下图:

  8. Solr6.6 创建core

    原文:https://github.com/x113773/testall/issues/7 1. 首先在solr-6.6.0目录运行命令,启动solr:`Linux: $ bin/solr star ...

  9. alt和title的区别与用法

    alt和title的是我们工作中经常用到这两个属性,但是一直没有总结他们的区别.现在就对他们两个的用法做一下总结.相同点:他们都会飘出一个小浮层,显示文本内容.不同点:1.alt只能是元素的属性,而t ...

  10. cssradius

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...