首页 > 其他分享 >做题笔记:洛谷P8966

做题笔记:洛谷P8966

时间:2023-02-02 10:58:41浏览次数:56  
标签:子树 洛谷 int 题解 电荷 P8966 笔记 long ans

考场没做出来。

赛后看了讲解PPT,补了,是一道很妙的题,所以来写一篇笔记。

尝试过交题解,但不给过,又见题解区已经有一篇非常好的非官方题解,个人也感觉写的太草也太抽象,达不到题解要求,就不占TA风头了,这仅仅是一篇笔记。

步入正题了

此题首先要注意一点:

不开long long见祖宗!(连挂两次)

正解:

首先考虑最优策略:

当一个点的两个子树未被装满时,两棵树的电荷显然差\(1\)或相等。

然后考虑神明的最优策略:显然要让球总是尽可能远离目标点。

所以相等时神明总是要选择远离目标方向。

所以当两棵子树差 \(1\) 时是凡人的唯一机会,此时可以让球相对靠近目标点。

那怎么做呢?

不妨考虑两次投球时球的电荷,倘若两棵子树未满。

当电荷不同时显然会同时落在一棵子树;

当电荷相同时则两个球必然会落在不同子树,

也就必然会有一个球相对靠近目标点,而这个球显然可以是当两棵子树电荷差 \(1\) 时投下的那个球。

所以凡人的一种最优策略显然是一直投正电或负电。

这样必然能保证两棵子树差 \(1\) 时让球相对靠近目标点。

这种策略确实一时很难理解,如果想更好地理解这种思路,可以将凡人和神明的最优策略带入样例模拟,这样很快就能明白。

一直投同一种电荷,显然让问题变成了模拟。

首先,球要填满目标点的子树。

然后发现:

设当前需要 \(ans\) 个球坠向目标点, \(c\) 表示旁边子树的大小,

则旁边的子树会落下 \(min(ans,c)\) 个球,新的 \(ans\) 显然是 \(ans+min(ans,c)\) 。

所以考虑不断从目标节点向上跳直到到了根节点不能再跳,每次更新 \(ans\) 。

最后就输出答案。

复杂度撑死是 \(O(n^2)\) ,也就是一条链,满足题意。

//writer:Oier_szc
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1005;
int n;
int fa[N],ch[N][3],c[N],sz[N];
void get_size(int u)
{
	sz[u]=c[u];
	for(int i=1;i<=ch[u][0];++i)
	{
		int to=ch[u][i];
		get_size(to);
		sz[u]+=sz[to];
	}
}
signed main()
{
	scanf("%lld",&n);
	for(int i=2;i<=n;++i)
	{
		scanf("%lld",&fa[i]);
		ch[fa[i]][++ch[fa[i]][0]]=i;
	}
	for(int i=1;i<=n;++i) scanf("%lld",&c[i]);
	get_size(1);
	for(int i=1;i<=n;++i)
	{
		int now=i,ans=sz[i];
		while(fa[now])
		{
			int this_ch=now,other_ch=-1;
			now=fa[now];
			for(int j=1;j<=ch[now][0];++j)
			{
				if(ch[now][j]!=this_ch) other_ch=ch[now][j];
			}
			if(other_ch==-1) continue;
			//other_ch==兄弟节点 
			ans+=min(sz[other_ch],ans);
		}
		printf("%lld ",ans);
	}
	return 0;
}

标签:子树,洛谷,int,题解,电荷,P8966,笔记,long,ans
From: https://www.cnblogs.com/StevenZC/p/17085238.html

相关文章

  • 扩展中国剩余定理学习笔记
    扩展中国剩余定理模板题:P4777前置芝士:扩展欧几里得(exgcd)不需要中国剩余定理问题:求\(\begin{cases}x\equivm_1\(\mod\a_1)\\x\equivm_2\(\mod\a_2)\\...\\x\equ......
  • 做题笔记:次短路(P2865)
    虽然算法难度达不到记笔记的级别但由于个人认为较为重要,故作记录。抓住最短路和次短路的一个区别,最少一条边不同。所以不妨正反(\(1\)和\(n\))分别跑最短路。然后枚......
  • (笔记)linux 之.service文件简介
     一、什么是.service文件?Linux中.service文件是某项服务对应的配置文件,可用于systemd管理和控制的服务的设置。.service文件通常包含3个模块,即[Unit]控制单元,表示启动......
  • 使用kubeadm安装k8s1.26.0笔记2
    一.安装版本Kubeadm使用cni方式安装版本:v1.26.0 二.机器准备1.机器规格本次安装1个master和1个node节点Master:192.168.64.6Node:192.168.64.7规则:CPU:2内存:4G系......
  • 读Java8函数式编程笔记08_测试、调试和重构
    1. Lambda表达式的单元测试1.1. 单元测试是测试一段代码的行为是否符合预期的方式1.2. Lambda表达式没有名字,无法直接在测试代码中调用1.2.1. 将Lambda表达式放入......
  • SpringBoot学习笔记 - 构建、简化原理、快速启动、配置文件与多环境配置、技术整合案
    【前置内容】Spring学习笔记全系列传送门:Spring学习笔记-第一章-IoC(控制反转)、IoC容器、Bean的实例化与生命周期、DI(依赖注入)Spring学习笔记-第二章-注解......
  • 「matlab学习笔记」MATLAB程序流程控制
    中国大学MOOC科学计算与MATLAB语言(点击此处跳转)MATLAB官方文档(点击此处跳转)3.1程序文件脚本文件和函数文件在MATLAB中程序文件的扩展名为.m,所以程序文件也称为M文件......
  • Per-Pixel Classification is Not All You Need for Semantic Segmentation论文阅读笔
    作者的解读:https://www.zhihu.com/search?type=content&q=MaskFormer摘要现有的语义分割方法将分割视为逐像素的分类,本文提出了MaskFormer,把分割转化为预测一系列的mask......
  • 离散化学习笔记
    本来应该配着一道题讲的因为太晚了就先咕咕了挖个坑虽然大概率应该不会填离散化简单来说就是当你需要用数组统计一些数的出现次数但数据范围过大(如1e9)无法使用数组存......
  • 线段树学习笔记
    本条目持续更新中线段树1:建树单点修改区间求和关于线段树:假如我们有这样一个数列33280721那我们就可以建一个线段树大概长这样:由图可知编号为i的左......