https://codeforces.com/contest/1062/problem/E

题意

给一颗树n,然后q个询问,询问编号l~r的点,假设可以删除一个点,使得他们的最近公共祖先深度最大。每次询问,输出删除的点和祖先的深度

思路

  • 考虑dfs序来判断v是否在u的子树里:

    dfn[u]<dfn[v]<=max(dfn[u的子树])

  • 那么进一步拓展,dfs序之差越大,点就在越分离的地方,这些点的lca一定是lca(max(dfn[u]),min(dfn[u]))
  • 这不仅知道了需要去掉哪个点(上述两个点之一),而且知道了怎么求点的lca
  • 然后枚举去掉两个点求lca(lca(l,u-1),lca(u+1,r))
  • 线段树维护最小,最大dfn的点
  1. #include<bits/stdc++.h>
  2. #define M 100005
  3. #define pb push_back
  4. #define inf 100000000
  5. using namespace std;
  6. struct N{
  7. int l,r;
  8. array<int,2>mi,ma;
  9. }tr[M<<2];
  10. vector<int>g[M];
  11. int n,q,i,d[M],pre[M],u,v,l,r,a,b,dfn,f[M][30];
  12. void push_up(int o){
  13. tr[o].mi=min(tr[o<<1].mi,tr[o<<1|1].mi);
  14. tr[o].ma=max(tr[o<<1].ma,tr[o<<1|1].ma);
  15. }
  16. int lca(int u,int v){
  17. if(d[v]>d[u])swap(u,v);
  18. int dis=d[u]-d[v];
  19. for(int i=20;i>=0;i--)if(dis&(1<<i))u=f[u][i];
  20. if(u==v)return u;
  21. for(int i=20;i>=0;i--)
  22. if(f[u][i]!=f[v][i]){u=f[u][i];v=f[v][i];}
  23. return f[u][0];
  24. }
  25. void dfs(int u,int fa){
  26. f[u][0]=fa;for(int i=1;i<=20;i++)f[u][i]=f[f[u][i-1]][i-1];
  27. d[u]=d[fa]+1;pre[u]=++dfn;
  28. //cout<<u<<" "<<d[u]<<endl;
  29. for(int i=0;i<g[u].size();i++){
  30. int v=g[u][i];
  31. dfs(v,u);
  32. }
  33. }
  34. void build(int o,int l,int r){
  35. tr[o].l=l;tr[o].r=r;
  36. if(l==r){
  37. tr[o].ma=tr[o].mi={pre[l],l};
  38. return;
  39. }
  40. int mid=(l+r)/2;
  41. build(o<<1,l,mid);
  42. build(o<<1|1,mid+1,r);
  43. push_up(o);
  44. }
  45. array<int,2> qy1(int o,int L,int R){
  46. int l=tr[o].l,r=tr[o].r,mid=(l+r)/2;
  47. if(L<=l&&r<=R)return tr[o].mi;
  48. array<int,2>ans={inf,n+1};
  49. if(L<=mid)ans=min(ans,qy1(o<<1,L,R));
  50. if(R>mid)ans=min(ans,qy1(o<<1|1,L,R));
  51. return ans;
  52. }
  53. array<int,2> qy2(int o,int L,int R){
  54. int l=tr[o].l,r=tr[o].r,mid=(l+r)/2;
  55. if(L<=l&&r<=R)return tr[o].ma;
  56. array<int,2>ans={0,n+1};
  57. if(L<=mid)ans=max(ans,qy2(o<<1,L,R));
  58. if(R>mid)ans=max(ans,qy2(o<<1|1,L,R));
  59. return ans;
  60. }
  61. int main(){
  62. dfn=0;
  63. cin>>n>>q;
  64. for(i=2;i<=n;i++){scanf("%d",&u);g[u].pb(i);}
  65. d[0]=-1; dfs(1,0);
  66. build(1,1,n);
  67. while(q--){
  68. scanf("%d%d",&l,&r);
  69. u=qy1(1,l,r)[1];v=qy2(1,l,r)[1];
  70. if(u==l)a=lca(qy1(1,l+1,r)[1],qy2(1,l+1,r)[1]);
  71. else if(u==r)a=lca(qy1(1,l,r-1)[1],qy2(1,l,r-1)[1]);
  72. else a=lca(lca(qy1(1,l,u-1)[1],qy2(1,l,u-1)[1]),lca(qy1(1,u+1,r)[1],qy2(1,u+1,r)[1]));
  73. if(v==l)b=lca(qy1(1,l+1,r)[1],qy2(1,l+1,r)[1]);
  74. else if(v==r)b=lca(qy1(1,l,r-1)[1],qy2(1,l,r-1)[1]);
  75. else b=lca(lca(qy1(1,l,v-1)[1],qy2(1,l,v-1)[1]),lca(qy1(1,v+1,r)[1],qy2(1,v+1,r)[1]));
  76. //cout<<u<<" "<<a<<endl;
  77. //cout<<v<<" "<<b<<endl;
  78. if(d[a]>d[b])printf("%d %d\n",u,d[a]);
  79. else printf("%d %d\n",v,d[b]);
  80. }
  81. }

Codeforces Round #520 (Div. 2) E. Company(dfs序判断v是否在u的子树里+lca+线段树)的更多相关文章

  1. Codeforces Round #520 (Div. 2)

    Codeforces Round #520 (Div. 2) https://codeforces.com/contest/1062 A #include<bits/stdc++.h> u ...

  2. Codeforces Round #520 (Div. 2) Solution

    A. A Prank Solved. 题意: 给出一串数字,每个数字的范围是$[1, 1000]$,并且这个序列是递增的,求最多擦除掉多少个数字,使得别人一看就知道缺的数字是什么. 思路: 显然,如果 ...

  3. Codeforces Round #459 (Div. 2) D. MADMAX DFS+博弈

    D. MADMAX time limit per test 1 second memory limit per test 256 megabytes input standard input outp ...

  4. Codeforces Round #222 (Div. 1) A. Maze dfs

    A. Maze 题目连接: http://codeforces.com/contest/377/problem/A Description Pavel loves grid mazes. A grid ...

  5. Codeforces Round #245 (Div. 2) C. Xor-tree DFS

    C. Xor-tree Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/430/problem/C ...

  6. Codeforces Round #398 (Div. 2) C. Garland —— DFS

    题目链接:http://codeforces.com/contest/767/problem/C 题解:类似于提着一串葡萄,用剪刀剪两条藤,葡萄分成了三串.问怎样剪才能使三串葡萄的质量相等. 首先要做 ...

  7. Codeforces Round #321 (Div. 2)C(tree dfs)

    题意:给出一棵树,共有n个节点,其中根节点是Kefa的家,叶子是restaurant,a[i]....a[n]表示i节点是否有猫,问:Kefa要去restaurant并且不能连续经过m个有猫的节点有多 ...

  8. Codeforces Round #267 (Div. 2)D(DFS+单词hash+简单DP)

    D. Fedor and Essay time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. Codeforces Round #527 (Div. 3)F(DFS,DP)

    #include<bits/stdc++.h>using namespace std;const int N=200005;int n,A[N];long long Mx,tot,S[N] ...

随机推荐

  1. idea不识别yml配置文件,怎么办?

      问题描述: 如下图,新建的springboot项目,添加了自定义的配置文件后,2.yml无法像上方文件的一样,被识别成配置文件! 虽然可能不会影响项目(不确定),但问题不解决,根本没有心情开始下一 ...

  2. android和js互相调用

    import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.o ...

  3. 在Eclipse中安装python插件的方法

    一个博士给了我一堆代码,原本以为是C++或者java写的,结果是python,我压根没学过呀,不过本着语言都是相通的原则,我硬着头皮开始学习Python,当然先学习安装IDE(以前学习一门新语言,我会 ...

  4. MYSQL 优化常用方法总结

    1, 选取最合适的字段属性以及长度 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快. 比如:定义邮政编码 char(6) 最合适,如果char(2 ...

  5. 同一台主机部署两个比特币钱包以及rpc服务的摘要

    .bitcoin QA Test环境 启动指定参数: "C:\Program Files (x86)\Bitcoin\bitcoin-qt.exe" -testnet -serve ...

  6. mysql 安装后出现 10061错误

    #服务器端  提示 The vervice already exists! The current server installed #mysqld 服务没有启动 解决办法 移除原来的mysql服务  ...

  7. python tcp 粘包问题解决、文件下载等

    from socket import * #以下是关于tcp:服务端 和 客户端的小例子#服务端socket_server = socket(AF_INET, SOCK_STREAM) socket_ ...

  8. Java图形化界面设计——GridBagConstraints

    JAVA布局模式:GridBagConstraints终极技巧参数详解 布局模式 :GridBagConstraints布局,先发一个实例: gridx = 2; // X2 gridy = 0; / ...

  9. android使用Pull解析来自服务器的xml文件时出现错误以及解决方案

    直接上代码,代码中有详细注释: 1 public class CheckUpdateManager { 2 private static final String TAG = "CheckU ...

  10. andorid 网格视图GridView

    .xml <?xml version="1.0" encoding="utf-8"?> <GridView xmlns:android=&qu ...