首页 > 其他分享 >14届蓝桥杯省赛E题——颜色平衡树

14届蓝桥杯省赛E题——颜色平衡树

时间:2024-03-14 22:31:31浏览次数:27  
标签:node 颜色 14 color 蓝桥 int num 重子 省赛

一、题目描述

二、题目分析

设颜色平衡树的节点有n个,颜色种类为p种,每种颜色的出现次数均为q,则n=p*q。换句话说,如果一棵树的出现次数最多的颜色们的出现次数之和等于该树的节点个数,那么这棵树是颜色平衡树。

为了降低遍历次数,采用树上启发式合并,定义树中节点最多的子树为重子树,其余为轻子树。

  1. 遍历轻子树,得到轻子树中的平衡树,但不保留颜色记录;
  2. 遍历重子树,得到重子树中的平衡树,保留颜色记录;
  3. 再次遍历轻子树,将轻子树节点的颜色记录贡献到重子树的颜色记录中;
  4. 判断这树是否为颜色平衡树;

三、代码

#include<bits/stdc++.h>
using namespace std;
#define N 200050

int color[N];//节点n的颜色
int heavy_son[N];//节点n的重儿子
int Size[N];//节点n的大小
int num[N];//颜色C出现的次数
int max_color_num;//出现次数最多的 颜色 出现的次数
int sum;//出现次数最多的 颜色们 的总出现次数
int ans;//颜色平衡树的数量
vector<int> child[N];//节点n的孩子

void Init_dfs(int node)
//计算每个子树的大小,记录在size[node]中;并且找到每个子树的重子树,记录在heavy[node]中。
{
	Size[node] = 1;
	for (auto it : child[node])
	{
		Init_dfs(it);
		Size[node] += Size[it];
		if (Size[it] > Size[heavy_son[node]])
			heavy_son[node] = it;
	}
}

void add(int node, bool option)
{
	int this_color = color[node];
	num[this_color]++;
	if (num[this_color] > max_color_num)
	{
		max_color_num = num[this_color];
		sum = num[this_color];
	}
	else if (num[this_color] == max_color_num)
		sum += num[this_color];

	
	for (auto it : child[node])
	{
		//首次调用时跳过重子树
		if (it == heavy_son[node] && option)
			continue;
		add(it, false);
	}
}

void sub(int node)
//sub函数将递归地从num[200010]中删除一个节点及其所有儿子的信息
{
	int this_color = color[node];
	num[this_color]--;
	for (auto it : child[node])
		sub(it);
}

void dfs(int node, bool option)
{
	for (auto it : child[node])
	//跳过重子树,遍历轻子树,计算轻子树中的结果,但不保留记录
	{
		if (it == heavy_son[node])
			continue;
		dfs(it, false);
	}

	if (heavy_son[node])
	//如果重子树存在,遍历重子树,计算出重子树中的结果,保留结果
		dfs(heavy_son[node], true);

	//遍历轻子树,保留记录,并与上一步相加
	add(node, true);
	//如果出现次数最多的颜色们的出现次数总和等于该树的大小
	if (sum == Size[node])
		ans++;
	//如果不保留该次次数,则对记录撤销
	if (!option)
	{
		sub(node);
		sum = 0;
		max_color_num = 0;
	}
}


int main()
{
	int n; cin >> n;
	for (int i = 1; i <= n; i++)
	{
		int p;
		cin >> color[i] >> p;
		child[p].emplace_back(i);
	}
	Init_dfs(1);
	dfs(1, true);
	cout << ans;
    return 0;
}

标签:node,颜色,14,color,蓝桥,int,num,重子,省赛
From: https://blog.csdn.net/m0_74261855/article/details/136602997

相关文章

  • 【10分钟掌握深度学习2】机器学习基础14
    2.30聚类和降维有什么区别与联系?聚类用于找寻数据内在的分布结构,既可以作为一个单独的过程,比如异常检测等等。也可作为分类等其他学习任务的前驱过程。聚类是标准的无监督学习。在一些推荐系统中需确定新用户的类型,但定义“用户类型”却可能不太容易,此时往往可先对原油......
  • P8681 [蓝桥杯 2019 省 AB] 完全二叉树的权值
    题目描述给定一棵包含N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是​,如下图所示: 现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。注:根的深度是 1......
  • 备战蓝桥杯Day27 - 省赛真题-2023
    题目描述大佬代码importosimportsysdeffind(n):k=0fornuminrange(12345678,98765433):str1=["2","0","2","3"]forxinstr(num):ifxinstr1:ifstr1[0]==x......
  • C++ | 蓝桥题库区间或(位运算)
    一开始看题解很晕,这里采用前缀和方式的思想是:按位贡献,将答案分成32份(1e9最多32位二进制数)这样才有的prefix[32][N]前缀和数组,求的是第i位数第w位上的和。(1<<w)1左移w位相当于2的w次方,prefix[w][r]-prefix[w][l-1]相当于[l,r]这段距离上有1就让ans加上1,没有就不加。#inc......
  • 2024/03/14
    今日学习web时长2小时代码行数大概40多行博客数量一篇今日依旧尝试Android连接MySQL,成功。今天开始配置gradle的本地仓库和镜像文件,完成后Androidstudio无法使用,找不到原因,应该是Androidstudio自动的配置的项目仓库和全局仓库不一样。所以最后还是老老实实的用gradle的默认......
  • springboot3/14
    在做系统首页配置时,#注意点,所有页面的静态资源都需要使用thymeleaf去接管;@{}页面国际化在项目中使用国际化我们需要配置i18n文件如果需要在项目中进行按钮自动切换功能,需要自己去定义一个国际化组件LocaleResolver配置完成后,记得将写好的组件配置到spring容器中@Bean在网页......
  • 蓝桥练习题-K倍区间
    16.k倍区间-蓝桥云课(lanqiao.cn)首先,看到这个题,想到暴力求解,但显然,数据过大,暴力法过不了;然后看到了一个办法:对所有元素的前缀和取K的模,若s[i],s[j]相同,则在j-1到i的区间内,区间和为K的倍数。C++代码:#include<iostream>#include<queue>usingnamespacestd;ty......
  • 蓝桥练习题-分考场
    0分考场-蓝桥云课(lanqiao.cn)思路:暴力dfs,dfs(x,room)x为待放入教室的人,room为当前最大有几号教室,对x依次遍历教室1到教室room,若某教室当前没该同学认识的人,直接放入,接着放下一个人,若room个教室里都存在x认识的人,即x不能放入任何教室,则在开辟一块新教室放入该同学,dfs结束......
  • 20240314打卡
    第三周第一天第二天第三天第四天第五天第六天第七天所花时间3h5h0h1h代码量(行)274256064博客量(篇)1111知识点了解完成AndroidStudio中原生数据库SQlite简单的CRUD本地数据库连接到远程数据库海底谭练习python的Pyautogui,自动操作G......
  • 更新用户基本信息 2024-3-14
    更新用户基本信息//usercontroller@PutMapping("/update")publicResultupdate(@RequestBodyUseruser){userService.update(user);returnResult.success();}//userServicevoidupdate(Useruser);//userServiceImpl@Override......