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. VMWare WorkStation15--Win10下开机启动虚拟机

    参考 https://www.cnblogs.com/qmfsun/p/6284236.html http://www.cnblogs.com/eliteboy/p/7838091.html VMWa ...

  2. 合并两个word文档,保持样式不变

    一.需求说明 例如将封面插入到word正文上方 二.导入依赖 <dependency> <groupId>org.apache.poi</groupId> < ...

  3. nginx log 切割

    /logs/nginx/*/*access.log { daily rotate 30 missingok dateext #compress notifempty sharedscripts pos ...

  4. Win10教育版VL版kms密钥激活

    1.右键开始图标,或者win+x,选择Windows PowerShell(管理员): 2.依次执行下面的命令,分别表示安装win10教育版密钥,设置kms服务器,激活win10教育版: slmgr ...

  5. JAVAEE 和项目开发(第一课:浏览器和服务器的交互模式和HTTP协议的概念和介绍)

    互联网的发展非常迅速,但是万变不离其宗.学习 web 开发,需要我们对互 联的交互机制有一定的了解.为了更好的理解并掌握 Servlet,在正式学习 Servlet之前需要对 web 开发中客户端和服 ...

  6. winform操作windows系统计算器

    winform对系统计算器的调用,启动,最大化最小化显示,在mainwindow设置topmost=true时,正常显示计算器并置顶. /// <summary> /// 获取窗体的句柄函 ...

  7. jstl中遍历Map

    在jstl中遍历Map和遍历List与数组一样,都是使用forEach标签. 例子: <%@ page import="java.util.Map" %> <%@ ...

  8. 201771010123汪慧和《面向对象程序设计Java》第十周实验总结

    一.理论部分 1.泛型:也称参数化类型.就是定义类.接口和方法时,通过类型参数指示将要处理的对象类型. 2.泛型程序设计:编写代码可以被很多不同类型的对象所重用. 3.泛型方法: a.除了泛型类外,还 ...

  9. 基于springboot实现Ueditor并生成.html的示例

    一.项目架构 二.项目代码 1.HtmlProductController.java package com.controller; import java.io.File; import java. ...

  10. Linux(CENTOS7) Tomcat服务成功发布但局域网浏览器无法访问

    问题 : 我在linux搭建了一个tomcat服务器,tomcat开启后,发现在局域网浏览器上无法访问该tomcat,浏览器报无法访问服务器错误,我查看了tomcat的日志,路径..../tomcat ...