题目链接: https://www.cometoj.com/contest/29/problem/A?problem_id=414

Aqours

题目描述

Aqours 正在 LoveLive! 决赛中表演,舞台可以看作是一棵 nn 个点的有根树,其中根节点是 1 号点,ii 号点的父亲节点为 p_ip

i



,保证 1 \le p_i < i1≤p

i



<i,而且对于 2 \le i < j \le n2≤i<j≤n 有 p_i \le p_jp

i



≤p

j



其中的叶子节点(定义为没有孩子节点的点)是与粉丝进行互动的节点,Aqours 会在这些叶子节点之间走动来与更多的粉丝互动,但是她们又要唱歌又要跳舞,要尽快节省走动时间,然后也要做到雨露均沾,所以每次要往编号更小的叶子节点走。

所以 Aqours 想知道对于每一个叶子节点 uu,离它最近的编号 < u<u 的叶子节点到它的距离是多少,若不存在则视距离为 -1。

输入描述

第一行一个正整数 n (1 \le n \le 3 \times 10^6)n(1≤n≤3×10

6

),表示树的大小。

第二行 n-1n−1 个正整数,其中第 ii 个数表示 p_{i+1}(1 \le p_{i+1} \le i)p

i+1



(1≤p

i+1



≤i)。

对于 2 \le i < j \le n2≤i<j≤n,保证 p_i \le p_jp

i



≤p

j



输出描述

每个叶子对应的答案输出一行。每行第一个数是叶子节点的编号 uu,第二个数是离他最近的编号 < u<u 的叶子节点到它的距离,若不存在则输出 -1。

要求按叶子节点编号从小到大输出。

样例输入 1

10

1 1 1 1 2 4 5 6 7

样例输出 1

3 -1

8 3

9 4

10 4

思路:

对于题面的这句话,我们可以把给定的点序列看为数的BFS序。

我们维护一个信息 dp[i] 代表距离第i个节点最近的叶子节点的距离。

我们从1到n,扫每一个叶子节点Y,我们向上(它的父节点)dfs,dfs过程中维护f的值,直到遇到一个已经访问(被其他节点dfs过得)的节点 X 。那么当前节点的答案就是 dp[X] +Y到X节点的步数。

同时还需要回溯更新dp[i] 的信息。

为什么正确?

1、我们是从1到n逐一扫描每一个叶子 节点Y,所以当一个叶子节点向上dfs的过程中遇到了一个已经放过的节点X时,X节点一定是被编号比Y小的节点更新的。所以保证了题目的要求。

2、我们在dfs过程中同时回溯维护dp[i] 的信息,就保证了dp[i] 即可以是其他节点通过先上后下到达的,也可以是下方的节点一直向上走到达的。

这样保证了dp[i] 的正确性。

细节见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int* p);
const int maxn = 3000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int du[maxn];
int far[maxn];
bool vis[maxn];
int n;
int ans;
int dp[maxn];
int dfs(int id,int step)
{
if(vis[id])
{
ans=dp[id]+step;
return dp[id]+1;
}else
{
int temp=inf;
dp[id]=step;
vis[id]=1;
if(id!=1)
{
temp=dfs(far[id],step+1);
}
if(temp<dp[id])
dp[id]=temp;
return dp[id]+1;
}
}
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
gg(n);
int x;
repd(i,2,n)
{
gg(x);
du[x]++;
far[i]=x;
}
repd(i,1,n)
{
ans=-1;
if(du[i]==0)
{
dfs(i,0);
printf("%d %d\n",i,ans);
}
} return 0;
} inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}

CCPC-Wannafly Winter Camp Day8 (Div2, onsite) A 题 Aqours (精巧的树形DP)的更多相关文章

  1. Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门  Portal  原题目描述在最下面.  简单的 ...

  2. CCPC-Wannafly Winter Camp Day8 (Div2, onsite) 补题

    A Aqours 题解: https://www.cnblogs.com/qieqiemin/p/11251645.html D:吉良吉影的奇妙计划 (暴力打表) 题目描述 吉良吉影是一个平凡的上班族 ...

  3. CCPC-Wannafly Winter Camp Day8 (Div2, onsite)

    咕咕咕.    camp补题. 传送门:https://www.zhixincode.com/contest/29/problems A.Aqours 题意:有一棵有根树,根节点为1,给出每个结点的父 ...

  4. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  5. CCPC-Wannafly Winter Camp Day5 (Div2, onsite) Sorting(线段树)

    题目链接 题意 对序列进行三种操作: 1.区间求和. 2.将区间小于等于$x$的数不改变相对顺序的前提下放到$x$左边,用同样规则将比$x$大的放到右边. 3.将区间大于$x$的数不改变相对顺序的前提 ...

  6. CCPC-Wannafly Winter Camp Day3 (Div2, onsite)

    Replay Dup4: 没想清楚就动手写? 写了两百行发现没用?想的还是不够仔细啊. 要有莽一莽的精神 X: 感觉今天没啥输出啊, 就推了个公式?抄了个板子, 然后就一直自闭A. 语文差,题目没理解 ...

  7. 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)

    solve:4/11 补题:6/11 A 机器人 补题:zz 这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细 ...

  8. CCPC Wannafly Winter Camp Div2 部分题解

    Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...

  9. 2019 CCPC-Wannafly Winter Camp Day7(Div2, onsite)

    solve 6/11 补题: A.迷宫 Code:zz Thinking:zz kk 把每个节点的深度都处理出来,同一深度的点的冲突度为 (x-1),x为同层次点数减一. 然后冲突度不断下传(冲突度为 ...

随机推荐

  1. 全面解读php-php会话控制技术

    一.PHP会话控制技术 1.为什么要使用会话控制技术? 因为http协议是无状态协议,所以同一个用户在请求同一个页面两次的时候,http协议不会认为这两次请求都来自于同一个用户,会把它们当做是两次请求 ...

  2. MSTest/NUnit 单元测试 代码覆盖率试用 OpenCover 和ReportGenerator

    VS自带是单元测试代码覆盖率(VS自带这个是最佳选择)需要企业版才有.很蛋疼...... 1.下载安装OpenCover 和ReportGenerator. 关于这2个是干啥的百度下.简单说就是可以分 ...

  3. 有关二次离线和 Yuno loves sqrt technology II

    二次离线 前置技能 莫队 修改查询 \(O(\sqrt n )-O(1)\) 平衡 概念 考虑朴素莫队离线询问,过程中维护信息从 \([l,r]\) 扩展为 \([l\pm 1,r\pm 1]\) , ...

  4. Ubuntu 16.04安装、卸载mysql及怎么使用SQL常用操作语句

    以前都是在window上操作,连接数据库,最近转Ubuntu系统,故此,记下安装过程 一,安装mysql,Ctrl+Alt+T打开终端,一步步分别输入命令 //安装mysql服务 sudo apt-g ...

  5. centos7.7下docker与k8s安装(DevOps三)

    1.系统配置 centos7.7 docker 1.13.1 centos7下安装docker:https://www.cnblogs.com/pu20065226/p/10536744.html 2 ...

  6. netfilter/iptables 防火墙

    目录 文章目录 目录 iptables 与 netfilter 工作机制 规则(Rules) 链(chain) 表(tables) 网络数据包通过 iptables 的过程 总结链.表和规则的关系 i ...

  7. Day02:正则表达式 / Object / 包装类

    JAVA正则表达式 实际开发中,经常需要对字符串数据进行一些复杂的匹配,查找,替换等操作. 通过"正则表达式",可以方便的实现字符串的复杂操作. 正则表达式是一串特定字符,组成一个 ...

  8. python学习之面向对象(二)

    6.2 类的空间角度研究类 6.2.1 添加对象属性 [总结]对象的属性不仅可以在__init__里面添加,还可以在类的其他方法或者类的外面添加. class A: address = '召唤师峡谷' ...

  9. USACO1.6 Superprime Rib

    题目传送门 每一个特殊质数都会被从右边切掉,所以除了首位外的其它位数一定都不会是偶数,只能是$1$,$3$,$5$,$7$,$9$ 而每一个特殊质数的首位一定是质数,也就是$2$,$3$,$5$,$7 ...

  10. Spring(九)--通知

    Spring之Advice通知 Spring原生的经典模式  实现AOPadvice :通知 前置通知:在目标方法执行之前执行!不能改变方法的执行流程和结果!            实现MethodB ...