You are given a tree that represents a hierarchy in a company, where the parent of node u is their direct manager.

Each employee is assigned a project, and multiple employees can be assigned to the same project. When it is time for the presentation of the ith project, all employees u that are assigned that project and their direct and indirect managers must attend the presentation (u and their manager and their manager's manager and so on until the CEO).

Find for each project the number of people attending its presentation.

Input

The first line of input is n and m (1 ≤ m ≤ n ≤ 106), the number of employees and the number of projects, respectively.

The second line of input contains n integers ai (1 ≤ ai ≤ m), where ai is the project assigned to the ith employee. It is guaranteed that each project has at least one employee assigned to it.

The third line of input contains n integers pi (0 ≤ pi ≤ n), where pi is the direct manager of the ith employee. If pi = 0, then the ith
employee is the CEO and does not have a manager. It is guaranteed that
there is only one CEO, and this CEO is a direct or indirect manager of
all other employees.

Output

Output m integers, where the ith integer is the number of people attending the presentation of the ith project.

Example

Input
6 4
1 2 4 3 2 4
0 1 1 3 3 2
Output
1 4 3 4 
题解:首先根据题意建树,每个节点有对应的任务(1~m),如果一个人处理i任务,那么他所有的祖先都得参与到当中,对于每一个任务,求参与到其中的人的数量。
首先DFS序跑图,得到每个节点的入时间序,时间序对应的原节点,深度,走2^0步得到的节点。
然后对于每一个任务:假设其中有x个人执行这个任务,我们首先将其按DFS序从小到大排序,然后有对应公式:sum+=dep[i]-dep[LCA(i-1,i)]。
那么就该想如何实现这个过程了,下面是用的vector存储:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=;
int w[maxn],x,root,cnt;
int Start[maxn],End[maxn],dep[maxn],par[][maxn],Rev[maxn];
vector<int>G[maxn],vv[maxn],ans;
void DFS(int u,int pre,int d)
{
par[][u]=pre;//u向上走2^0走到pre节点
dep[u]=d;//u的深度
Start[u]=++cnt;//DFS序对应值
Rev[cnt]=u;//将其反过来转换为原来的节点
for(int i=;i<G[u].size();i++){
DFS(G[u][i],u,d+);
}
End[u]=cnt;
}
int LCA(int u,int v)
{
if(dep[u]>dep[v])swap(u,v);
for(int k=;k<;k++){//让u和v走到同一深度
if((dep[v]-dep[u])>>k&){//这里简单理解下就是将u和v的距离用二进制表示,每一位1将其变为0
v=par[k][v];
}
}
if(u==v)return u;
for(int k=;k>=;k--){
if(par[k][u]!=par[k][v]){
u=par[k][u];
v=par[k][v];
}
}
return par[][u];
}
int main()
{
ios::sync_with_stdio();
int n,m;
cin>>n>>m;
for(int i=;i<=n;i++)cin>>w[i];
for(int i=;i<=n;i++){
cin>>x;
if(x!=){
G[x].push_back(i);
}
else
root=i;
}
DFS(root,-,);
for(int k=;k<;k++){//预处理par数组
for(int v=;v<=n;v++){
if(par[k][v]==-)par[k+][v]=-;
else par[k+][v]=par[k][par[k][v]];
}
}
for(int i=;i<=n;i++){
vv[w[i]].push_back(Start[i]);
}
for(int i=;i<=m;i++){
sort(vv[i].begin(),vv[i].end());//按照DFS序递增排序,是为了不重复答案
int sum=;
for(int j=;j<vv[i].size();j++){
if(j==)sum+=dep[Rev[vv[i][j]]];
else sum+=dep[Rev[vv[i][j]]]-dep[LCA(Rev[vv[i][j-]],Rev[vv[i][j]])];
}
ans.push_back(sum);
}
for(int i=;i<ans.size();i++)cout<<ans[i]<<" ";
cout<<endl;
return ;
}

D - Project Presentation(DFS序+倍增LCA)的更多相关文章

  1. P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA

    \(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...

  2. luogu3320 寻宝游戏 (dfs序+倍增lca+set)

    一定是从随便某个点开始,然后按着dfs序的顺序跑一圈是最好的 所以说,新加一个点x,就减少了dis(pre,next),增加了dis(pre,x),dis(x,nxt) 删掉一个点同理 这个可以用se ...

  3. 洛谷P3379 【模板】最近公共祖先(LCA)(dfs序+倍增)

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

  4. dfs序 + RMQ = LCA

    dfs序是指你用dfs遍历一棵树时,每个节点会按照遍历到的先后顺序得到一个序号.然后你用这些序号,可以把整个遍历过程表示出来. 如上图所示,则整个遍历过程为1 2 3 2 4 5 4 6 4 2 1 ...

  5. bzoj 2819 Nim(BIT,dfs序,LCA)

    2819: Nim Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1596  Solved: 597[Submit][Status][Discuss] ...

  6. bzoj3306: 树(dfs序+倍增+线段树)

    比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...

  7. CF 208E - Blood Cousins dfs序+倍增

    208E - Blood Cousins 题目:给出一棵树,问与节点v的第k个祖先相同的节点数有多少个. 分析: 寻找节点v的第k个祖先,这不就是qtree2简化版吗,但是怎么统计该祖先拥有多少个深度 ...

  8. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  9. 蓝皮书:异象石 【dfs序+lca】

    题目详见蓝皮书[算法竞赛:进阶指南]. 题目大意: 就是给你一颗树,然后我们要在上面进行三种操作:  1.标记某个点  或者  2.撤销某个点的标记  以及   3.询问标记点在树上连通所需的最短总边 ...

随机推荐

  1. 学习spring的第一天

    1.首先在maven repository中找到Spring Context依赖添加进模块 2.配置xml,resources右键new→xml configuration file→Spring C ...

  2. 每天一点点之vue框架开发 - vue坑-This relative module was not found

    94% asset optimization ERROR Failed to compile with 1 errors This relative module was not found: * . ...

  3. Python String startswith() Method

    一,摘自官方API  https://docs.python.org/3/library/stdtypes.html#methods str.startswith(prefix[, start[, e ...

  4. Cracking Digital VLSI Verification Interview 第一章

    目录 Digital Logic Design Number Systems, Arithmetic and Codes Basic Gates Combinational Logic Circuit ...

  5. 京东云携手Mellanox,设计最先进SDN硬件加速功能并开源

    京东云携手Mellanox,设计最先进SDN硬件加速功能并开源 最新技术播报 京东云开发者社区  导语新一代 SDN.NFV 和云原生计算技术正在推动应用实例的极限,这些实例可以在虚拟化和容器化的服务 ...

  6. PAT B1038 统计同成绩学生超时问题

    输入格式: 输入在第 1 行给出不超过 10​5​​ 的正整数 N,即学生总人数.随后一行给出 N 名学生的百分制整数成绩,中间以空格分隔.最后一行给出要查询的分数个数 K(不超过 N 的正整数),随 ...

  7. 开始新建AEM站点-周末教程

    Getting Started Developing AEM Sites - WKND Tutorial 开始新建AEM站点-周末教程 The goal for this multi-part tut ...

  8. uploadify ASP.net 使用笔记

    <script type="text/javascript" src="jquery.uploadify.min.js"></script & ...

  9. RepeatSubmitInterceptor extends HandlerInterceptorAdapter

    package com.ruoyi.framework.interceptor; import java.lang.reflect.Method; import javax.servlet.http. ...

  10. ruoyi ShiroUtils

    package com.ruoyi.framework.util; import org.apache.shiro.SecurityUtils; import org.apache.shiro.cry ...