bzoj 2500: 幸福的道路 动态规划+单调栈

博客介绍了如何解决bzoj 2500题目,即寻找一棵树中最长的区间[l, r],使得区间内点权的最大值与最小值之差不超过m。通过求解每个节点的最长路径和次长路径,并利用单调栈避免数据结构导致的超时问题,实现高效求解。最后,博主分享了1A大法在解决此类问题上的应用。" 104636356,2429791,使用Podofo处理PNG透明度问题,"['PDF处理', 'C++', '图像处理', '开源库']
摘要由CSDN通过智能技术生成

题意

给出一棵树,每条边都有一个长度。我们规定每个点的权值为从该点开始走过的一条最长的路径的长度。
求一个最长的区间[l,r],使得[l,r]里面点权的最大值和最小值只差不超过m。
n<=1000000

分析

首先我们要把点权求出来。
那么我们设1为根节点,用两个数组fir[i]和sec[i]维护从节点i开始最长的路径和次长的路径。
第一次先求出起点为i终点在i的子树内的最长路和次长路,第二次再求出每个节点往其父节点走的最长路径。
接着就要求最大的区间,这里我一开始的想法是用数据结构来维护,set或者线段树什么的应该都行,但是我们注意到n<=1000000,则这么干有可能会超时。
那么我们就改用单调栈来维护最大值和最小值。
第一个单调栈保证里面的元素严格递增,第二个单调栈保证里面的元素严格递减,那么最大值就是第二个单调栈的栈底,最小值就是第一个单调栈的栈顶,我们只需要每次插入i时同时维护这两个单调栈即可。

1A大法好!!!

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N 1000005
using namespace std;

int n,m,last[N],cnt;
struct edge{
  int to,len,next;}e[N*2];
struct stack{
  int len,id;}stack1[N],stack2[N];
struct data{
  int num,len;}fir[N],sec[N];

void addedge(int u,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值