题目链接:https://vjudge.net/problem/POJ-3162

题意:给一棵树,求每个结点的树上最远距离,记为a[i],然后求最大区间[l,r]满足区间内的max(a[i])-min(a[i])<=M。

思路:第一步向hdoj2196那题一样树形dp求出每个结点的最长距离,我的另一篇博客中有写到https://www.cnblogs.com/FrankChen831X/p/11375572.html。求出最远距离a[i]后,建立线段树维护区间的最大最小值。然后用两个指针i,j遍历一遍,每次求出[i,j]的最大最小值ans1和ans2,更新答案,因为j每次不用初始化,总复杂度为O(nlogn)。

AC代码:

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4.  
  5. typedef long long LL;
  6. const int maxn=1e6+;
  7. const LL inf=0x3f3f3f3f3f3f3f3f;
  8. int n,ans,cnt,head[maxn],pt[maxn],a[maxn];
  9. LL M,dp[maxn][],ans1,ans2;
  10.  
  11. struct node1{
  12. int v,nex;
  13. LL w;
  14. }edge[maxn<<];
  15.  
  16. struct node2{
  17. int l,r;
  18. LL Max,Min;
  19. }tr[maxn<<];
  20.  
  21. void adde(int u,int v,LL w){
  22. edge[++cnt].v=v;
  23. edge[cnt].w=w;
  24. edge[cnt].nex=head[u];
  25. head[u]=cnt;
  26. }
  27.  
  28. void dfs1(int u,int fa){
  29. for(int i=head[u];i;i=edge[i].nex){
  30. int v=edge[i].v;
  31. LL w=edge[i].w;
  32. if(v==fa) continue;
  33. dfs1(v,u);
  34. if(w+dp[v][]>dp[u][]){
  35. dp[u][]=dp[u][];
  36. dp[u][]=w+dp[v][];
  37. pt[u]=v;
  38. }
  39. else if(w+dp[v][]>dp[u][])
  40. dp[u][]=w+dp[v][];
  41. }
  42. }
  43.  
  44. void dfs2(int u,int fa){
  45. for(int i=head[u];i;i=edge[i].nex){
  46. int v=edge[i].v;
  47. LL w=edge[i].w;
  48. if(v==fa) continue;
  49. if(v!=pt[u])
  50. dp[v][]=w+max(dp[u][],dp[u][]);
  51. else
  52. dp[v][]=w+max(dp[u][],dp[u][]);
  53. dfs2(v,u);
  54. }
  55. }
  56.  
  57. void pushup(int v){
  58. tr[v].Max=max(tr[v<<].Max,tr[v<<|].Max);
  59. tr[v].Min=min(tr[v<<].Min,tr[v<<|].Min);
  60. }
  61.  
  62. void build(int v,int l,int r){
  63. tr[v].l=l,tr[v].r=r;
  64. if(l==r){
  65. tr[v].Max=tr[v].Min=a[l];
  66. return;
  67. }
  68. int mid=(l+r)>>;
  69. build(v<<,l,mid);
  70. build(v<<|,mid+,r);
  71. pushup(v);
  72. }
  73.  
  74. void query(int v,int l,int r){
  75. if(l<=tr[v].l&&r>=tr[v].r){
  76. ans1=max(ans1,tr[v].Max);
  77. ans2=min(ans2,tr[v].Min);
  78. return;
  79. }
  80. int mid=(tr[v].l+tr[v].r)>>;
  81. if(l<=mid) query(v<<,l,r);
  82. if(r>mid) query(v<<|,l,r);
  83. }
  84.  
  85. int main(){
  86. scanf("%d%lld",&n,&M);
  87. for(int i=;i<=n;++i){
  88. int v;LL w;
  89. scanf("%d%lld",&v,&w);
  90. adde(i,v,w);
  91. adde(v,i,w);
  92. }
  93. dfs1(,);
  94. dfs2(,);
  95. for(int i=;i<=n;++i)
  96. a[i]=max(dp[i][],dp[i][]);
  97. build(,,n);
  98. int j=;
  99. for(int i=;i<=n;++i){
  100. while(j<=n){
  101. ans1=,ans2=inf;
  102. query(,i,j);
  103. if(ans1-ans2>M) break;
  104. ++j;
  105. }
  106. ans=max(ans,j-i);
  107. }
  108. printf("%d\n",ans);
  109. return ;
  110. }

poj3162(树形dp+线段树求最大最小值)的更多相关文章

  1. POJ 3162 Walking Race 树形DP+线段树

    给出一棵树,编号为1~n,给出数m 漂亮mm连续n天锻炼身体,每天会以节点i为起点,走到离i最远距离的节点 走了n天之后,mm想到知道自己这n天的锻炼效果 于是mm把这n天每一天走的距离记录在一起,成 ...

  2. hdu5293 Tree chain problem 树形dp+线段树

    题目:pid=5293">http://acm.hdu.edu.cn/showproblem.php?pid=5293 在一棵树中,给出若干条链和链的权值.求选取不相交的链使得权值和最 ...

  3. Codeforces 671D. Roads in Yusland(树形DP+线段树)

    调了半天居然还能是线段树写错了,药丸 这题大概是类似一个树形DP的东西.设$dp[i]$为修完i这棵子树的最小代价,假设当前点为$x$,但是转移的时候我们不知道子节点到底有没有一条越过$x$的路.如果 ...

  4. 【洛谷5298】[PKUWC2018] Minimax(树形DP+线段树合并)

    点此看题面 大致题意: 有一棵树,给出每个叶节点的点权(互不相同),非叶节点\(x\)至多有两个子节点,且其点权有\(p_x\)的概率是子节点点权较大值,有\(1-p_x\)的概率是子节点点权较小值. ...

  5. Codeforces Round #530 (Div. 2) F (树形dp+线段树)

    F. Cookies 链接:http://codeforces.com/contest/1099/problem/F 题意: 给你一棵树,树上有n个节点,每个节点上有ai块饼干,在这个节点上的每块饼干 ...

  6. Codeforces Round #530 (Div. 2)F Cookies (树形dp+线段树)

    题:https://codeforces.com/contest/1099/problem/F 题意:给定一个树,每个节点有俩个信息x和t,分别表示这个节点上的饼干个数和先手吃掉这个节点上一个饼干的的 ...

  7. 2016年湖南省第十二届大学生计算机程序设计竞赛---Parenthesis(线段树求区间最值)

    原题链接 http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1809 Description Bobo has a balanced parenthes ...

  8. ZOJ 3349 Special Subsequence 简单DP + 线段树

    同 HDU 2836 只不过改成了求最长子串. DP+线段树单点修改+区间查最值. #include <cstdio> #include <cstring> #include ...

  9. CS Academy Gcd on a Circle(dp + 线段树)

    题意 给你一个长为 \(n\) 的环,你可以把它断成任意 \(k\) 段 \((1 < k \le n)\) ,使得每一段的 \(\gcd\) 都 \(>1\) . 问总共有多少种方案,对 ...

随机推荐

  1. MFC 画笔CPen、画刷CBrush

    新建单个文档的MFC应用程序,类视图——View项的属性——消息,WM_PAINT,创建OnPaint()函数 dc默认有一个画笔(实心1像素宽黑线). CPen画笔非实心线像素宽必须为1,否则膨胀接 ...

  2. MFC GDI绘图

    DC——MFC设备描述表类(也叫设备环境.设备上下文).默认起始点(0,0),带To的函数会移动起始点到指定位置. 新建单个文档的MFC应用程序,类视图——View项的属性——消息,WM_PAINT, ...

  3. delphi将两个Strlist合并,求并集

    Function StrList_Merge(StrListA,StrListB:String):String; //将两个Strlist合并,求并集 var SListA,SListB,SListC ...

  4. xgboost 特征重要性计算

    在XGBoost中提供了三种特征重要性的计算方法: ‘weight’ - the number of times a feature is used to split the data across ...

  5. 决策树算法的Python实现—基于金融场景实操

    决策树是最经常使用的数据挖掘算法,本次分享jacky带你深入浅出,走进决策树的世界 基本概念 决策树(Decision Tree) 它通过对训练样本的学习,并建立分类规则,然后依据分类规则,对新样本数 ...

  6. java线程之sleep

    翻译:https://www.journaldev.com/1020/thread-sleep-java 简述 Thread .sleep()方法用来暂停当前线程的执行,以毫秒为单位.还有另一个重载方 ...

  7. 引发了未经处理的异常:读取访问权限冲突。 _First 是 nullptr。

    1.问题:程序崩溃出现错误 引发了未经处理的异常:读取访问权限冲突. _First 是 nullptr. string strreponse=0: 定义这条语句,字符串初始化错误. 自己开发了一个股票 ...

  8. python性能测试值timeit的使用示例

    from timeit import Timer def t1(): li = [] for i in range(10000): li.append(i) def t2(): li = [] for ...

  9. asp.net webAPI

    Get: 1.Get参数传递的本质是url字符串拼接:2.url字符串长度受限制:3.Get参数传递在Http请求头部传递,而不支持Request-Body传递:4.Get类型的方法支持参数为基本类型 ...

  10. 初写C#的小总结

    虽然大学学过很多计算机语言,但是现在工作是前端,一个刚入行的前端菜鸟,之前对于后台完全零接触,但是最近有个项目,我也是第一次真正接触C#,中间遇到了一些小问题,就做个总结记录下,真的是超级简单的小知识 ...