给定一棵n个点并且有边权的树,每个点的权值为该点能走的最远长度,并输入m个询问,每次询问最多有多少个编号连续的点,他们的最大最小点权差小于等于Q。N<=50000 M<=500 Q<=10000000

  我们知道一个点能走的最远端点一定是树的直径的端点,所以我们只需从树的直径两端点dfs,就可以求出每个点能到的最远长度。。然后rmq+尺取即可。

这道题如果用系统的log会tle,所以必须手打log2。原理会再放一篇博客。

 #include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn=, maxmi=, INF=1e9;
//const double exp=1e-6;
int n, m, cntedge, maxdist, maxdistpos;
int fir[maxn], val[maxn];
int fmaxm[maxn][maxmi], fminm[maxn][maxmi];
struct Edge{
int to, v, next;
};
Edge edge[maxn]; void addedge(int x, int y, int z){
++cntedge;
Edge &nowedge1=edge[cntedge];
nowedge1.to=y, nowedge1.v=z, nowedge1.next=fir[x];
fir[x]=cntedge;
++cntedge;
Edge &nowedge2=edge[cntedge];
nowedge2.to=x, nowedge2.v=z, nowedge2.next=fir[y];
fir[y]=cntedge;
return;
} void dfs(int now, int par, int dist){
int nowedge, nowson;
nowedge=fir[now];
while (nowedge){
nowson=edge[nowedge].to;
if (nowson==par){
nowedge=edge[nowedge].next;
continue;
}
dfs(nowson, now, dist+edge[nowedge].v);
nowedge=edge[nowedge].next;
}
if (dist>val[now]) val[now]=dist;
if (dist>maxdist){
maxdist=dist;
maxdistpos=now;
}
return;
} int flog2(float x) {
return ((unsigned&)x>>&)-;
}
int dvalue(int head, int tail){
int maxm=, minm=1e9;
int lognum=flog2(tail-head+);
maxm=max(fmaxm[head][lognum], fmaxm[tail-(<<lognum)+][lognum]);
minm=min(fminm[head][lognum], fminm[tail-(<<lognum)+][lognum]);
return maxm-minm;
} void init(){
memset(fir, , sizeof(fir));
memset(val, , sizeof(val));
for (int i=; i<maxn; ++i){
edge[i].next=edge[i].to=edge[i].v=;
}
cntedge=;
} int ri(){
char c;
int flag=, r=;
do{
c=getchar();
if (c=='-') flag=-;
} while (!isgraph(c));
do{
r=r*+c-;
c=getchar();
} while (isgraph(c));
return r*flag;
} int main(){
int x, y, z;
while (~scanf("%d%d", &n, &m)){
if (n==&&m==) break;
init();
for (int i=; i<n; ++i){
x=ri(), y=ri(), z=ri();
addedge(x, y, z);
}
int s=, far1, far2;
maxdist=, dfs(s, , );
far1=maxdistpos;
maxdist=, dfs(far1, , );
far2=maxdistpos;
maxdist=, dfs(far2, , );
//for (int i=1; i<=n; ++i)
//printf("%d\n", val[i]);
int q=;
for (int i=; i<=n; ++i)
fmaxm[i][]=fminm[i][]=val[i];
for (int i=; i<maxmi; ++i){
for (int j=; j<=n-(<<i)+; ++j){
fmaxm[j][i]=max(fmaxm[j][i-], fmaxm[j+(<<(i-))][i-]);
fminm[j][i]=min(fminm[j][i-], fminm[j+(<<(i-))][i-]);
}
}
int h=, t=, maxm=;
for (int i=; i<m; ++i){
q=ri();
h=, t=, maxm=;
while (t<=n){
if (dvalue(h, t)<=q) ++t;
else ++h;
if ((t-h)>maxm) maxm=t-h;
}
printf("%d\n", maxm);
}
}
return ;
}

树的直径+rmq+(伪)单调队列 -HDU4123的更多相关文章

  1. 【bzoj1999】[Noip2007]Core树网的核 树的直径+双指针法+单调队列

    题目描述 给出一棵树,定义一个点到一条路径的距离为这个点到这条路径上所有点的距离的最小值.求一条长度不超过s的路径,使得所有点到这条路径的距离的最大值最小. 输入 包含n行: 第1行,两个正整数n和s ...

  2. hdu 4123 Bob’s Race 树的直径+rmq+尺取

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...

  3. 51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)

    题目链接 \(Description\) 给定一棵树.每次询问给定\(a\sim b,c\sim d\)两个下标区间,从这两个区间中各取一个点,使得这两个点距离最远.输出最远距离. \(n,q\leq ...

  4. HDU - 5289 Assignment (RMQ+二分)(单调队列)

    题目链接: Assignment  题意: 给出一个数列,问其中存在多少连续子序列,使得子序列的最大值-最小值<k. 题解: RMQ先处理出每个区间的最大值和最小值(复杂度为:n×logn),相 ...

  5. 求最长的任意两元素差不超过M的子段——双指针+单调队列hdu4123

    换根dp的部分比较容易,难点在于求求最长的任意两元素差不超过M的子段 首先会想到双指针维护(尺取法),如果p1,p2间的max-min>M,那么p1向右移动,直到p1,p2间的max-min&g ...

  6. 洛谷 P2216 [HAOI2007]理想的正方形 || 二维RMQ的单调队列

    题目 这个题的算法核心就是求出以i,j为左上角,边长为n的矩阵中最小值和最大值.最小和最大值的求法类似. 单调队列做法: 以最小值为例: q1[i][j]表示第i行上,从j列开始的n列的最小值.$q1 ...

  7. HDU 4123 Bob’s Race 树的直径 RMQ

    Bob’s Race Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=41 ...

  8. 【HDU6701】Make Rounddog Happy【权值线段树+双向单调队列】

    题意:给你一个序列,求满足要求的子序列个数,其中要求为: 1.子序列的max-子序列长度len<=k 2.子序列中不出现重复的数字 题解:首先看到子序列max,很容易想到枚举最大值然后分治,这个 ...

  9. cf1208 E Let Them Slide(差分+RMQ\单调队列)

    题意 如题目的图所示,每行都可以左右移动,但是数字不允许断开,且不许越界(宽度为w). 单独求每一列的最大的和为多少. 思路 对于每一列来说,在每一行上都有一个可以取到的区间, 所以,对于一列来说,答 ...

随机推荐

  1. Mysql备份和还原(命令)

    1.备份方法一 ①.进入数据库 mysql -uroot -p pwd; ②.查看数据库 show databases; ③.备份数据库 mysqldump -hlocalhost -uroot(用户 ...

  2. 代码题(14)— 合并有序链表、数组、合并K个排序链表

    1.21. 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出 ...

  3. Vue2.0 探索之路——vuex入门教程和思考

    Vuex是什么 首先对于vuex是什么,我先引用下官方的解释. Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可 ...

  4. hdu-5637 Transform(位运算+bfs)

    题目链接: Transform Time Limit: 4000/2000 MS (Java/Others)     Memory Limit: 131072/131072 K (Java/Other ...

  5. 详细详解One Hot编码-附代码

    机器学习算法无法直接用于数据分类.数据分类必须转换为数字才能进一步进行. 在本教程中,你将发现如何将输入或输出的序列数据转换为一种热编码,以便于你在Python中深度学习的序列分类问题中使用.本教程分 ...

  6. 经过一年时间的沉淀 再次回首 TCP Socket服务器编程 (二)

    ------------------ 前言 ------------------ 发了第一篇文章后,有不少同志留言,看来socket编程仍然是软件系统里面一个比较难的部分. 第一篇文章主要介绍了传输协 ...

  7. javascript:function 函数声明和函数表达式 详解

    函数声明(缩写为FD)是这样一种函数: 有一个特定的名称 在源码中的位置:要么处于程序级(Program level),要么处于其它函数的主体(FunctionBody)中 在进入上下文阶段创建 影响 ...

  8. 人物-IT-张志东:张志东

    ylbtech-人物-IT-张志东:张志东 张志东,广东东莞人,腾讯创办人之一,腾讯高级副总裁兼科技总裁,于1993年取得深圳大学理学学士学位,并于1996年取得华南理工大学计算机应用及系统架构硕士学 ...

  9. JWT(JSON WEB TOKEN) / oauth2 / SSL

    1: JWT: 为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景.JWT的声明一般被 ...

  10. 问题:部署到iis上后Chart图片不显示;结果:使用webchart过程中遇到的一些问题

    使用webchart过程中遇到的一些问题 2013年04月30日 ⁄ 综合 ⁄ 共 4874字 ⁄ 字号 小 中 大 ⁄ 评论关闭   安装条件:1.操作系统如果是2003的,那么需要到sp2补丁2. ...