HDU 4123 Bob’s Race 树的直径+ST表
Bob’s Race
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://acm.hdu.edu.cn/showproblem.php?pid=4123
Description
Input
There are several test cases.
The first line of each test case contains two integers N and M. N is the number of houses, M is the number of queries.
The following N-1 lines, each contains three integers, x, y
and z, indicating that there is a road of length z connecting house x
and house y.
The following M lines are the queries. Each line contains an
integer Q, asking that at most how many people can take part in Bob’s
race according to the above mentioned rules and under the condition that
the“race difference”is no more than Q.
The input ends with N = 0 and M = 0.
(N<=50000 M<=500 1<=x,y<=N 0<=z<=5000 Q<=10000000)
Output
For each test case, you should output the answer in a line for each query.
Sample Input
1 2 3
2 3 4
4 5 3
3 4 2
1
2
3
4
5
0 0
Sample Output
1
3
3
3
5
HINT
题意
一个城镇有N个住户,N-1条路连接两个住户,保证N个住户联通,M次询问,给定N条边的信息,包括连
接的住户序号以及路的长度。然后是M次询问,每次询问Q,要求找到最长的连续序号(我一开始看成了树上连续一段),使得Max(dis[i]) - Min(dis[i]) ≤
Q(l≤i≤r),输出最大的r-l+1。dis[i]为从第i个住户出发,不重复走过路能移动的最远距离。
题解:
1.首先需要知道一个 结论:树上每个节点理他最远的点肯定是数的直径的两个端点的其中一个。
2.如果你不会求树的直径以及两个端点,没关系,其实不难,任意找一个点dfs找到离它最远的点root1,root1一定是其中一个端点,然后再以root1为根dfs一遍求出理root1最远的点root2。这样就找到了两个端点。
3.求出每个点到最远点的距离,我这里是分别以root1,root2 dfs,求出每个点到root1和root2的距离,取个max即可。
4.题目转化成了,求最长的区间(l,r),满足max{l,r}-min{l,r}<=q。
5.其实可以用尺取法来做,因为假如(l,r)区间合法,那么(l+1,r)一定合法,那么枚举左端点,右端点只能单增,时间复杂度是O(n)的。
6.最后要搞个ST表求区间最大最小值。
我一开始用优先队列做的,然后T了,真是花样作死,非要加个log。
衷心提示:k=(int)(log(y-x+1)/2)会超时,这个需要预处理,亲测一个1.5s,另一个5.2秒。
优先队列tle代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 50050
int n,m,val[N],dp1[N],dp2[N],flag[N];
int tot,last[N];
struct Edge{int from,to,val,s;}edges[N<<];
struct Node
{
int id,val;
bool operator <(const Node&b)const
{return val<b.val;}
};
template<typename T>void read(T&x)
{
ll k=; char c=getchar();
x=;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit();
while(isdigit(c))x=x*+c-'',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
void AddEdge (int x,int y,int z)
{
edges[++tot]=Edge{x,y,z,last[x]};
last[x]=tot;
}
void dfs1(int x,int pre,int &mx,int &root)
{
mx=; root=x;
int tpmx,tproot;
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==pre)continue;
dfs1(e.to,x,tpmx,tproot);
if (tpmx+e.val>mx)
{
mx=tpmx+e.val;
root=tproot;
}
}
}
void dfs2(int x,int pre,int *dp)
{
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==pre)continue;
dp[e.to]=dp[x]+e.val;
dfs2(e.to,x,dp);
}
} void init()
{
read(n); read(m);
if (n==&&m==)exit();
for(int i=;i<=n-;i++)
{
int x,y,z;
read(x); read(y); read(z);
AddEdge(x,y,z);
AddEdge(y,x,z);
}
int maxn=,root1,root2;
dfs1(,,maxn,root1);
dfs1(root1,,maxn,root2);
dfs2(root1,,dp1);
dfs2(root2,,dp2);
for(int i=;i<=n;i++) val[i]=max(dp1[i],dp2[i]);
}
void solve()
{
int r=,ans=,q;
read(q);
priority_queue<Node>Qmx,Qmi;
memset(flag,,sizeof(flag));
for(int i=;i<=n;i++)
{
while(r+<=n&&(Qmx.empty()||
(fabs(val[r+]-Qmx.top().val)
<=q&&fabs(val[r+]+Qmi.top().val)<=q)))
{
Qmx.push(Node{r+,val[r+]});
Qmi.push(Node{r+,-val[r+]});
r++;
}
ans=max(ans,r-i+);
flag[i]=;
while(!Qmx.empty()&&flag[Qmx.top().id])Qmx.pop();
while(!Qmi.empty()&&flag[Qmi.top().id])Qmi.pop();
}
printf("%d\n",ans);
}
void clear()
{
tot=;
memset(last,,sizeof(last));
memset(dp1,,sizeof(dp1));
memset(dp2,,sizeof(dp2));
memset(flag,,sizeof(flag));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
while()
{
clear();
init();
for(int i=;i<=m;i++) solve();
}
}
ST表AC代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 50050
int n,m,dp1[N],dp2[N],mx[N][],mi[N][],mm[N];
int tot,last[N];
struct Edge{int from,to,val,s;}edges[N<<];
template<typename T>void read(T&x)
{
ll k=; char c=getchar();
x=;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit();
while(isdigit(c))x=x*+c-'',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
void AddEdge (int x,int y,int z)
{
edges[++tot]=Edge{x,y,z,last[x]};
last[x]=tot;
}
void dfs1(int x,int pre,int &mx,int &root)
{
mx=; root=x;
int tpmx,tproot;
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==pre)continue;
dfs1(e.to,x,tpmx,tproot);
if (tpmx+e.val>mx)
{
mx=tpmx+e.val;
root=tproot;
}
}
}
void dfs2(int x,int pre,int *dp)
{
for(int i=last[x];i;i=edges[i].s)
{
Edge &e=edges[i];
if (e.to==pre)continue;
dp[e.to]=dp[x]+e.val;
dfs2(e.to,x,dp);
}
} void init()
{
read(n); read(m);
if (n==&&m==)exit();
for(int i=;i<=n-;i++)
{
int x,y,z;
read(x); read(y); read(z);
AddEdge(x,y,z);
AddEdge(y,x,z);
}
int maxn=,root1,root2;
dfs1(,,maxn,root1);
dfs1(root1,,maxn,root2);
dfs2(root1,,dp1);
dfs2(root2,,dp2);
for(int i=;i<=n;i++) mx[i][]=mi[i][]=max(dp1[i],dp2[i]);
}
void init_ST()
{
mm[]=-;
for(int i=;i<=n;i++)mm[i]=(i&(i-))==?mm[i-]+:mm[i-];
for(int i=;i<=;i++)
for(int j=;j+(<<i)-<=n;j++)
{
mx[j][i]=max(mx[j][i-],mx[j+(<<(i-))][i-]);
mi[j][i]=min(mi[j][i-],mi[j+(<<(i-))][i-]);
}
}
int rmq(int x,int y)
{
int k=mm[y-x+];
int ans=max(mx[x][k],mx[y-(<<k)+][k]);
ans-=min(mi[x][k],mi[y-(<<k)+][k]);
return ans;
}
void solve()
{
int r=,ans=,q;
read(q);
for(int i=;i<=n;i++)
{
while(r+<=n&&rmq(i,r+)<=q)r++;
ans=max(ans,r-i+);
}
printf("%d\n",ans);
}
void clear()
{
tot=;
memset(last,,sizeof(last));
memset(dp1,,sizeof(dp1));
memset(dp2,,sizeof(dp2));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
clock_t now=clock();
while()
{
clear();
init();
init_ST();
for(int i=;i<=m;i++) solve();
} }
HDU 4123 Bob’s Race 树的直径+ST表的更多相关文章
- 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 ...
- hdu 4123 Bob’s Race 树的直径+rmq+尺取
Bob’s Race Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Probl ...
- HDU 4123 Bob’s Race 树的直径+单调队列
题意: 给定n个点的带边权树Q个询问. 以下n-1行给出树 以下Q行每行一个数字表示询问. 首先求出dp[N] :dp[i]表示i点距离树上最远点的距离 询问u, 表示求出 dp 数组中最长的连续序列 ...
- [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)
[51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...
- HDU 4123 Bob's Race:树的直径 + 单调队列 + st表
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 题意: 给你一棵树,n个节点,每条边有长度. 然后有m个询问,每个询问给定一个q值. 设dis[ ...
- HDU 4123 Bob’s Race 树形dp+单调队列
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...
- hdu 4123 Bob’s Race (dfs树上最远距离+RMQ)
C - Bob’s Race Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Subm ...
- HDU 4123 Bob’s Race(树形DP,rmq)
Bob’s Race Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 刷题总结——Bob's Race(hdu4123 树形dp+st表)
题目: Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the ro ...
随机推荐
- 【线性代数】2-6:三角矩阵( $A=LU$ and $A=LDU$ )
title: [线性代数]2-6:三角矩阵( A=LUA=LUA=LU and A=LDUA=LDUA=LDU ) toc: true categories: Mathematic Linear Al ...
- Centos 7 搭建蓝鲸V4.1.16稳定社区版
在本地用VMware模拟了三台主机 准备至少3台 CentOS 7 以上操作系统的机器,保证三台虚拟机都可以上网 最低配置:2核4G(我用的是这个) 建议配置: 4核12G 以上 192.168.16 ...
- T2695 桶哥的问题——吃桶 题解
校内测试 ------T3 对于这个题,首先想到的应该就是暴力枚举了吧,看看数据范围,60就是白送的啦!(但是我也不知道怎么才20分qwq) 思路分析: 这个题要你求所有套餐的总价值,先看一眼产生套餐 ...
- Postgres copy命令导入导出数据
最近有需要对数据进行迁移的需求,由于postgres性能的关系,单表3000W的数据量查询起来有一些慢,需要对大表进行切割,拆成若干个子表,涉及到原有数据要迁移到子表的需求.起初的想法是使用存储过程, ...
- js判断是否联网
// navigator.onLine if (navigator.onLine){ //正常工作 console.log("在线状态............................ ...
- PHP 二维数组去重方法
php二维数组的去重策略,如果需要根据某字段去重(其他字段可能不一致),那么需要使用循环策略,如果去重的都是相同的(字段,值),那么可以用序列化方式. $allComments = array_map ...
- Android 网络请求Retrofit + RxJava
一.背景 经常看到项目用Retrofit+RxJava+RxAndroid的框架,为了看懂项目的结构.现在来了解一下,Retrofit: Retrofit是Square 公司开发的一款正对Androi ...
- Handler注意事项
一. Handler与Thread的区别. Handler与调用者处于同一线程,如果Handler里面做耗时的动作,调用者线程会阻塞.Android UI操作不是线程安全的,并且这些操作必须在UI线程 ...
- JVM源码分析之JDK8下的僵尸(无法回收)类加载器[z]
[z]http://lovestblog.cn/blog/2016/04/24/classloader-unload/ 概述 这篇文章基于最近在排查的一个问题,花了我们团队不少时间来排查这个问题,现象 ...
- swagger-ui 系统配置过程(基于spring+springmvc+swagger+springfox配置 web-api 管理系统)
web工程部分框架信息:spring springmvc swagger springfox maven 参考文档:https://www.cnblogs.com/exmyth/p/7183753.h ...