Codeforces Round #520 (Div. 2) E. Company(dfs序判断v是否在u的子树里+lca+线段树)
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的点
#include<bits/stdc++.h>
#define M 100005
#define pb push_back
#define inf 100000000
using namespace std;
struct N{
int l,r;
array<int,2>mi,ma;
}tr[M<<2];
vector<int>g[M];
int n,q,i,d[M],pre[M],u,v,l,r,a,b,dfn,f[M][30];
void push_up(int o){
tr[o].mi=min(tr[o<<1].mi,tr[o<<1|1].mi);
tr[o].ma=max(tr[o<<1].ma,tr[o<<1|1].ma);
}
int lca(int u,int v){
if(d[v]>d[u])swap(u,v);
int dis=d[u]-d[v];
for(int i=20;i>=0;i--)if(dis&(1<<i))u=f[u][i];
if(u==v)return u;
for(int i=20;i>=0;i--)
if(f[u][i]!=f[v][i]){u=f[u][i];v=f[v][i];}
return f[u][0];
}
void dfs(int u,int fa){
f[u][0]=fa;for(int i=1;i<=20;i++)f[u][i]=f[f[u][i-1]][i-1];
d[u]=d[fa]+1;pre[u]=++dfn;
//cout<<u<<" "<<d[u]<<endl;
for(int i=0;i<g[u].size();i++){
int v=g[u][i];
dfs(v,u);
}
}
void build(int o,int l,int r){
tr[o].l=l;tr[o].r=r;
if(l==r){
tr[o].ma=tr[o].mi={pre[l],l};
return;
}
int mid=(l+r)/2;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
push_up(o);
}
array<int,2> qy1(int o,int L,int R){
int l=tr[o].l,r=tr[o].r,mid=(l+r)/2;
if(L<=l&&r<=R)return tr[o].mi;
array<int,2>ans={inf,n+1};
if(L<=mid)ans=min(ans,qy1(o<<1,L,R));
if(R>mid)ans=min(ans,qy1(o<<1|1,L,R));
return ans;
}
array<int,2> qy2(int o,int L,int R){
int l=tr[o].l,r=tr[o].r,mid=(l+r)/2;
if(L<=l&&r<=R)return tr[o].ma;
array<int,2>ans={0,n+1};
if(L<=mid)ans=max(ans,qy2(o<<1,L,R));
if(R>mid)ans=max(ans,qy2(o<<1|1,L,R));
return ans;
}
int main(){
dfn=0;
cin>>n>>q;
for(i=2;i<=n;i++){scanf("%d",&u);g[u].pb(i);}
d[0]=-1; dfs(1,0);
build(1,1,n);
while(q--){
scanf("%d%d",&l,&r);
u=qy1(1,l,r)[1];v=qy2(1,l,r)[1];
if(u==l)a=lca(qy1(1,l+1,r)[1],qy2(1,l+1,r)[1]);
else if(u==r)a=lca(qy1(1,l,r-1)[1],qy2(1,l,r-1)[1]);
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]));
if(v==l)b=lca(qy1(1,l+1,r)[1],qy2(1,l+1,r)[1]);
else if(v==r)b=lca(qy1(1,l,r-1)[1],qy2(1,l,r-1)[1]);
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]));
//cout<<u<<" "<<a<<endl;
//cout<<v<<" "<<b<<endl;
if(d[a]>d[b])printf("%d %d\n",u,d[a]);
else printf("%d %d\n",v,d[b]);
}
}
Codeforces Round #520 (Div. 2) E. Company(dfs序判断v是否在u的子树里+lca+线段树)的更多相关文章
- Codeforces Round #520 (Div. 2)
Codeforces Round #520 (Div. 2) https://codeforces.com/contest/1062 A #include<bits/stdc++.h> u ...
- Codeforces Round #520 (Div. 2) Solution
A. A Prank Solved. 题意: 给出一串数字,每个数字的范围是$[1, 1000]$,并且这个序列是递增的,求最多擦除掉多少个数字,使得别人一看就知道缺的数字是什么. 思路: 显然,如果 ...
- 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 ...
- Codeforces Round #222 (Div. 1) A. Maze dfs
A. Maze 题目连接: http://codeforces.com/contest/377/problem/A Description Pavel loves grid mazes. A grid ...
- 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 ...
- Codeforces Round #398 (Div. 2) C. Garland —— DFS
题目链接:http://codeforces.com/contest/767/problem/C 题解:类似于提着一串葡萄,用剪刀剪两条藤,葡萄分成了三串.问怎样剪才能使三串葡萄的质量相等. 首先要做 ...
- Codeforces Round #321 (Div. 2)C(tree dfs)
题意:给出一棵树,共有n个节点,其中根节点是Kefa的家,叶子是restaurant,a[i]....a[n]表示i节点是否有猫,问:Kefa要去restaurant并且不能连续经过m个有猫的节点有多 ...
- 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 ...
- 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] ...
随机推荐
- ios应用内嵌h5页面数据自动变色识别为手机号码的解决方法——手机号码拨号禁用IOS手机页面数字自动识别为手机号
异常如下: ios应用内嵌h5页面,本来是设置了白色的数字,两三秒之后会自动变为黑色,然后点击的时候就会弹出是否拨号的提示: 解决方法: 添加如下meta标签,即可解决: <meta name= ...
- 项目总结14:Windows远程连接redis(cmd指令或PowerShell指令)
1-确认远程的redis服务器是否允许被远程连接,已redis server安装在阿里云ECS上为例 1-1-确认在阿里云控制台,开放了端口6379和允许访问的IP 1-2-确认在服务器上安装redi ...
- 项目总结01:JSP mysql SpringMvc下中国省市县三级联动下拉框
JSP mysql SpringMvc下中国省市县三级联动下拉框 关键词 JSP mysql数据库 SpringMvc ajax Controller层 Service层 中国地区 省 ...
- MVC 的那点小事
两年未见 一切从头再来.我猜到了故事的开头,找工作一如我想象的那般艰难,但是结果却比我预期的要好很多. 第一次开始用MVC 框架,比我想象的要简单的多,就像同事跟我说的,这只是个框架. 言归正传,前两 ...
- C# 关闭进程的时候总是捕捉到System.Threading.ThreadAbortException: 正在中止线程
C# 关闭进程的时候总是捕捉到System.Threading.ThreadAbortException: 正在中止线程 这是由ThreadAbortException抛出的 可以写成下面的样子 tr ...
- ES6 WeakMap和WeakSet的使用场景
JavaScript垃圾回收是一种内存管理技术.在这种技术中,不再被引用的对象会被自动删除,而与其相关的资源也会被一同回收. Map和Set中对象的引用都是强类型化的,并不会允许垃圾回收.这样一来,如 ...
- sublime 注释模版插件DocBlockr的使用
一.gihub地址 https://github.com/spadgos/sublime-jsdocs/ 其中有使用的教程可以参考 二.配置示例 安装教程此处略,请自行查找教程 jsdocs_extr ...
- Java 8.9 游戏:井字游戏(C++&Java)
思路框架同8.20 : C++: #include<iostream> #include<string> using namespace std; class Chess { ...
- hdu 1394(线段树) 最小逆序数
http://acm.hdu.edu.cn/showproblem.php?pid=1394 给出一列数组,数组里的数都是从0到n-1的,在依次把第一个数放到最后一位的过程中求最小的逆序数 线段树的应 ...
- less 官网讲解 ( http://www.bootcss.com/p/lesscss/ )
变量 变量允许我们单独定义一系列通用的样式,然后在需要的时候去调用.所以在做全局样式调整的时候我们可能只需要修改几行代码就可以了. // LESS @color: #4D926F; #header { ...