给定一棵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. WebForm 使用点滴。。。。

    WebForm使用方式与WinForm很是相似,可控性非常高! 1.调用别的按钮事件: BtnSelect_Click(sender, e);

  2. 机器学习(十九)— xgboost初试kaggle

     1.官网下载kaggle数据集Homesite Competition数据集,文件结构大致如下: 2.代码实战 #Parameter grid search with xgboost #featur ...

  3. WCF的宿主

    接下来继续WCF(网上的方法)(实例) 1.无废话WCF入门教程一与无废话WCF入门教程二(http://www.cnblogs.com/iamlilinfeng/archive/2012/09/25 ...

  4. BEC listen and translation exercise 48

    It's not publicly known who the kidnappers were. Because they are not eating such lovely food since ...

  5. Canvas drawImage

    drawImage() 方法在画布上绘制图像.画布或视频. drawImage() 方法也能够绘制图像的某些部分,以及/或者增加或减少图像的尺寸. 这个方法有三张传参模式,3个参数,5个参数,9个参数 ...

  6. hdu-5650 so easy(水题)

    题目链接: so easy Time Limit: 2000/1000 MS (Java/Others)   Memory Limit: 65536/65536 K (Java/Others)Tota ...

  7. Linux-解决putty无法直接使用root用户远程登录linux主机的问题

    问题描述: 有时,在使用putty连接远程linux主机时会发现,无法直接使用root登录, 但是可以使用其他用户登录,然后切换至root用户. 解决办法: 1.修改配置文件 vi /etc/ssh/ ...

  8. Failed to install xxxx.apk on device 'emulator-5554!

    异常信息:[HelloAndroid] Performing com.example.helloandroid.HelloAndroid activity launch[HelloAndroid] U ...

  9. C++ 0X 新特性实例(比较常用的) (转)

    转自:http://www.cnblogs.com/mrblue/p/3141456.html //array #include <array> void Foo1() { array&l ...

  10. AAC_LC用LATM封装header信息解析 Audio Specific Config格式分析

    通常来说AAC的头信息在编解码过程中是可以获取到的,但今天需要根据音频参数生成相应的AAC头.项目中使用的是AAC_LC,今天先对它的结构进行分析. 项目中使用ffmpeg进行音频编码,音频编码库为F ...