当前位置:网站首页>(2022牛客多校三)A-Ancestor(LCA)
(2022牛客多校三)A-Ancestor(LCA)
2022-07-27 06:16:00 【AC__dream】
题目:
样例1输入:
5 3
5 4 3
6 6 3 4 6
1 2 2 4
7 4 5 7 7
1 1 3 2样例1输出:
1样例2输入:
10 3
10 9 8
8 9 9 2 7 9 0 0 7 4
1 1 2 4 3 4 2 4 7
7 7 2 3 4 5 6 1 5 3
1 1 3 1 2 4 7 3 5样例2输出:
2题意:给出两棵编号为1~n的树A,B,A树和B树上每个节点均有一个权值,给出k个关键点编号x1,x2……,xk,问有多少种方案使得去掉一个关键点使得剩余关键点在树A上的LCA的权值大于树B上LCA的权值。
注意:此处的去掉一个关键点只是不考虑它而已,并不是真正意义上的不能经过这个点什么的,比如去掉第1个特殊点,意思就是在原树上求解x2……,xk的LCA。
分析:LCA就是树上公共祖先,不会LCA的小伙伴可以看下这里:最近公共祖先(LCA)(树上倍增)_AC__dream的博客-CSDN博客_最近公共祖先
这道题我们可以预处理出来关键点序列在A树和B树上的前缀LCA和后缀LCA
代码中变量:
lcaprea[i]表示a中前i个点中的特殊点的LCA值,lcasufa[i]表示a中点i~n中的特殊点的LCA值
lcapreb[i]表示b中前i个点中的特殊点的LCA值,lcasufb[i]表示b中点i~n中的特殊点的LCA值
比如求解去掉第i个特殊点剩余的特殊点在A树上和B上的LCA,那么就是求解求解x1,x2……,xi-1,xi+1,……,xk在A树上和B树上的LCA,由于我们已经预处理出来了LCA前后缀,那么x1,x2……,xi-1,xi+1,……,xk在A树上的LCA就是lcaprea[i-1]和lcasufa[i+1]在A树上的最近公共祖先,x1,x2……,xi-1,xi+1,……,xk在B树上的LCA就是lcapreb[i-1]和lcasufb[i+1]在B树上的最近公共祖先。那么我们就可以直接枚举所有的特殊点进行判断即可。
下面是代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=1e6+10;
bool vis[N];
int wa[N],wb[N],fa[N][21],fb[N][21];
int h1[N],e1[N*10],ne1[N*10],idx;
int h2[N],e2[N*10],ne2[N*10],d1[N],d2[N];
int lcaprea[N],lcasufa[N];//lcaprea[i]表示a中前i个点中的特殊点的lca值,lcasufa[i]表示a中点i~n中的特殊点的lca值
int lcapreb[N],lcasufb[N];//lcapreb[i]表示b中前i个点中的特殊点的lca值,lcasufb[i]表示b中点i~n中的特殊点的lca值
void add(int x,int y,int p)
{
if(p==1)
{
e1[idx]=y;
ne1[idx]=h1[x];
h1[x]=idx++;
}
else
{
e2[idx]=y;
ne2[idx]=h2[x];
h2[x]=idx++;
}
}
void dfs1(int x,int father)
{
d1[x]=d1[father]+1;//计算深度
fa[x][0]=father;
for(int i=1;i<=20;i++)
fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=h1[x];i!=-1;i=ne1[i])
{
int j=e1[i];
if(j==father) continue;
dfs1(j,x);
}
}
void dfs2(int x,int father)
{
d2[x]=d2[father]+1;//计算深度
fb[x][0]=father;
for(int i=1;i<=20;i++)
fb[x][i]=fb[fb[x][i-1]][i-1];
for(int i=h2[x];i!=-1;i=ne2[i])
{
int j=e2[i];
if(j==father) continue;
dfs2(j,x);
}
}
int lca(int x,int y,int op)
{
if(x==0) return y;
if(y==0) return x;
if(op==1)
{
if(d1[x]<d1[y]) swap(x,y);
for(int i=20;i>=0;i--)//需要先将x和y移至同一高度
if(d1[fa[x][i]]>=d1[y])
x=fa[x][i];
if(x==y) return x;
for(int i=20;i>=0;i--)
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
return fa[x][0];
}
else
{
if(d2[x]<d2[y]) swap(x,y);
for(int i=20;i>=0;i--)//需要先将x和y移至同一高度
if(d2[fb[x][i]]>=d2[y])
x=fb[x][i];
if(x==y) return x;
for(int i=20;i>=0;i--)
if(fb[x][i]!=fb[y][i])
{
x=fb[x][i];
y=fb[y][i];
}
return fb[x][0];
}
}
int main()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=k;i++)
{
int t;
scanf("%d",&t);
vis[t]=true;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&wa[i]);
h1[i]=h2[i]=-1;
}
for(int i=2;i<=n;i++)
{
int t;
scanf("%d",&t);
add(t,i,1);
}
for(int i=1;i<=n;i++)
scanf("%d",&wb[i]);
for(int i=2;i<=n;i++)
{
int t;
scanf("%d",&t);
add(t,i,2);
}
dfs1(1,-1);
dfs2(1,-1);
int lca1=-1,lca2=-1;
for(int i=1;i<=n;i++)
{
if(vis[i])
{
if(lca1==-1) lca1=lca2=i;
else
{
lca1=lca(lca1,i,1);
lca2=lca(lca2,i,2);
}
}
}
int t=0;
for(int i=1;i<=n;i++)
{
if(vis[i])
{
if(!t) t=i;
else t=lca(t,i,1);
}
lcaprea[i]=t;
}
t=0;
for(int i=n;i>=1;i--)
{
if(vis[i])
{
if(!t) t=i;
else t=lca(t,i,1);
}
lcasufa[i]=t;
}
t=0;
for(int i=1;i<=n;i++)
{
if(vis[i])
{
if(!t) t=i;
else t=lca(t,i,2);
}
lcapreb[i]=t;
}
t=0;
for(int i=n;i>=1;i--)
{
if(vis[i])
{
if(!t) t=i;
else t=lca(t,i,2);
}
lcasufb[i]=t;
}
int ans=0;
for(int i=1;i<=n;i++)
if(vis[i])
{
int ta=lca(lcaprea[i-1],lcasufa[i+1],1);
int tb=lca(lcapreb[i-1],lcasufb[i+1],2);
if(wa[ta]>wb[tb]) ans++;
}
printf("%d",ans);
return 0;
}
边栏推荐
- Codeforces Round #804 (Div. 2)(5/5)
- centos7中关闭oracle服务自动启动的功能
- Flutter实战-请求封装(一)
- 使用反射实现动态修改@Excel的注解属性
- (转帖)eureka、consul、nacos的对比1
- Drools (5): drools basic syntax (3)
- Jmeter: interface automation test - BeanShell compares database data and return data
- 【QT】capture.obj:-1: error: LNK2019: 无法解析的外部符号 __imp_htons(解决方法)
- functools模块
- 端口转发小结
猜你喜欢

Drools (5): drools basic syntax (3)

Esp8266 (esp-12f) third party library use -- sparkfun_ Apds9960 (gesture recognition)

How to implement Devops with automation tools | including low code and Devops application practice

pytorch笔记:TD3

String类的用法

C# 常用功能整合-3

2022 0726 顾宇佳 学习笔记

Jmeter: interface automation test - BeanShell compares database data and return data

Quartus: an error is reported when adding a.V file to someone else's project

How MySQL executes query statements
随机推荐
Firefox browser, when accessing Tencent cloud server, failed to establish a secure connection.
Drools(5):Drools高级语法
DDD Domain Driven Design Notes
How to submit C4d animation to cloud rendering farm for fast rendering?
What is OKR and what is the difference between OKR and KPI
SQLite 常用功能整合
Pan Aimin, chairman of instruction set, attended the 2022 ecug con to speak for China's technical forces
Convert Excel to csv/csv UTF-8
Es compares the data difference between the two indexes
Logcat tool
tableau prep连接maxcompute,只是书写很简单的sql,为啥报这个错误呢?
零号培训平台课程-2、SSRF基础
Calledprocesserror during pre commit install
Instruction set x digital technology accelerates the digital transformation of government and enterprises, and builds Unicorn enterprise alliance in DT field
Internal class -- just read this article~
软件测试十大必问面试题(附答案和解析)
"Weilai Cup" 2022 Niuke summer multi school training camp 1
Tableau prep is connected to maxcompute and only writes simple SQL. Why is this error reported?
12. Integer to Roman整数转罗马数字
Automatically generate UML sequence diagram according to text (draw.io format)