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 ...
随机推荐
- vue项目更换目录后执行npm run dev 就报错(新手进)
在我们搭建好一个VUE项目的环境后,觉得这个项目存放的位置不好,想移动一下,但是移动后我们发现执行npm run dev就会报下面的错误: 明明只是移动了一下位置,就报错,实在是太恶心了. 但是只要我 ...
- 理解TCP三次握手和四次挥手
TCP相关知识 TCP是面向连接的传输层协议,它提供可靠交付的.全双工的.面向字节流的点对点服务.HTTP协议便是基于TCP协议实现的.(虽然作为应用层协议,HTTP协议并没有明确要求必须使用TCP协 ...
- python 鼠标输入
import win32con import win32api import time win32api.SetCursorPos([,]) # 设置鼠标位置 time.sleep(0.1) #win ...
- Django-内置的auth模块
一.auth认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Django作为一个 ...
- ios端浏览器拍照上传到服务器,图片被旋转90度 php 解决方案
1.可以通过前端进行解决,本案例通过后端解决的 判断请求的浏览器的ua,如果是ios浏览器则进行90度旋转 重点来了: 必须确保检测的图片是ios设备上传的完整图片,不要在前端压缩过的,因为压缩后的图 ...
- OpenDayLight安装Features
OpenDayLight 0.4.4-Beryllium-SR4 opendaylight-user@root>feature:install odl-restconf opendaylight ...
- golang——reverse反转字符串
reverse反转,是个比较基础算法.要实现这个方法,从常理考虑可以申请一个新空间,然后将字符串的从尾到头依次填充该空间,最后新空间的内容就是反转后的结果了,这个方式的算法复杂度是O(n),并且还需要 ...
- Qt Model/View 的简单说明
目录: (一) Qt Model/View 的简单说明 .预定义模型 (二)使用预定义模型 QstringListModel例子 (三)使用预定义模型QDirModel的例子 (四)Qt实现自定义模型 ...
- instanceof 实现
A instanceof B // 实现 instanceof function instance(a, b) { const proto = a.__proto__; // eslint-disab ...
- IDEA快捷键(修改成eclipse版)+Templates
快捷键:使用快捷键需要下载改建的配置文件,默认eclipse版的按键还是不全的. 链接:https://pan.baidu.com/s/17H4tFh__k6rExGpAf8NRJg 密码:rnl3 ...