暑假2019培训:Day2提高组测试赛

这篇博客记录了2019暑假提高组的训练情况,涉及三道C++编程题的详细解析,包括‘小刚传说’、‘中珂院的难题’和‘欧拉图’。‘小刚传说’是关于树结构的路径长度问题,‘中珂院的难题’是数列操作,‘欧拉图’则探讨了欧拉回路的计数问题。文章详述了题目要求、输入输出格式以及解题思路。
摘要由CSDN通过智能技术生成

概述

今天我们的Chty_syq放了点水,第一题来了个水题……
但我依旧考的不好

题目顺序

  • 1. 小刚传说
  • 2. 中珂院的难题
  • 3. 欧拉图

1. 小刚传说

(legendary.cpp)
【 时空限制】

时间限制: 2s
空间限制: 256MB

【 问题描述】

众所周知, 刘小刚是海亮中学的金牌教练, 然而世人并不知道他的传奇经历, 以及那个
曾经轰动世界的名字 sharpland。
2003 年, 美国研究团队在量子计算机的研制上取得了重大突破, 一旦美国成功研发出
量子计算机, 一切加密手段都将形同虚设。 当此之时, 国内第一黑客 sharpland 秘密潜入美
国中央情报局, 得知关于量子计算机的研究成果封存于五角大楼计算机群之中。 经过一周的
0Day 挖掘, sharpland 成功侵入计算机群, 却发现这里的文件保护机制非同寻常。
五角大楼计算机群的文件形成了树结构, 且树的形态随时间变化。 已知初始时刻树上仅
有一个根节点 1, 当成功拷贝结点 i 上的文件时, 树上会新增结点 i+1, 它的父亲为一个已
存在的结点。 树的大小增加为 n 时便会停止。
sharpland 通过之前挖掘的 0Day 成功推算出了所有新增结点的父亲, 为了破解文件保护
系统, 他需要在每次新增结点后新增的结点 i 和上一次新增的结点 i-1 的路径长度。

【 输入格式】

第一行, 一个整数 n 表示最终树的大小。
接下来 n-1 行, 每行一个整数表示新增节点的父亲。

【 输出格式】

共 n-1 行, 每行一个整数表示答案。

【 输入输出样例 1】
l e g e n d a r y . i n legendary.in legendary.in

6
1
2
2
1
5

legendary.out

1
1
2
3
1

【 输入输出样例 2】
l e g e n d a r y . i n legendary.in legendary.in

10
1
1
3
1
2
3
6
1
8

legendary.out

1
2
1
3
3
4
5
4
5

【 数据范围】

对于 30%的数据, n ≤100
对于 60%的数据, n ≤ 2000
对于 100%的数据, 2 ≤n ≤ 200000

【 后记】

sharpland 成功窃取数据的那一刻, 中央情报局察觉到了数据失窃并发布全球通缉令,
sharpland 隐姓埋名逃会国内, 以刘小刚为化名, 以高中竞赛教练为掩护, 生活至今。 然而
第一黑客 sharpland 之名早已响彻世界。

============
题面真有意思,不是吗?
这题是全场防暴零的水平,我只有这题拿了100分,于是乎,89人47名,比昨天稍差点
不过在C班被虐很正常~

这题是很明显的LCA

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,k,len;
int a[N],b[N],last[N*2],dis[N],fa[N][102];
bool vis[N];
struct ss
{
   
	int next,to;
}e[N*4];
void insert(int x,int y)
{
   
	e[++len].to=y;
	e[len].next=last[x];
	last[x]=len;
}
void dfs(int x,int root)
{
   
	if(vis[x])return;
	vis[x]=1;
	if(dis[x]==0&&x!=1)dis[x]=root;
	else dis[x]=min(dis[x],root);
	for(int i=last[x];i;i=e[i].next)
	{
   
		int y=e[i].to;
		if(y==fa[x][0])continue;
		fa[y][0]=x;
		dfs(y,root+1);
	}
}
void _find()
{
   
	for(int j=1;(1<<j)<n;++j)
	  for(int i=0;++i<=n;)
	    if(fa[i][j-1]==-1)fa[i][j]=-1;
	    else fa[i][j]=fa[fa[i][j-1]][j-1];
}
int LCA(int u,int v)
{
   
	if(dis[u]>dis[v])swap(u,v);
	for(int j=dis[v]-dis[u],i=0;j;j>>=1,++i)if(j&1)v=fa[v][i];
	if(u==v)return u;
	for(int i=24;i>=0;--i)
	  if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];
    return fa[u][0];
}
int main()
{
   
	freopen("legendary.in","r",stdin);
	freopen("legendary.out","w",stdout);
	int i,j,x,y;
    for(scanf("%d",&n),a[0]=1,i=0;++i<n&&scanf("%d",&x);a[i]=a[i-1]+1,insert(a[i],x),insert(x,a[i]));
    fa[1][0]=-1;
    dfs(1,0);
    _find();
    for(i=0;++i<n;)
    printf("%d\n",dis[a[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值