[P3899 [湖南集训] 更为厉害]

news/2025/1/11 16:46:43/文章来源:https://www.cnblogs.com/LG017/p/18665860

P3899 [湖南集训] 更为厉害

[湖南集训] 更为厉害

题目描述

\(\text T\) 为一棵有根树,我们做如下的定义:

  • \(a\)\(b\)\(\text T\) 中的两个不同节点。如果 \(a\)\(b\) 的祖先,那么称“\(a\)\(b\) 更为厉害”。
  • \(a\)\(b\)\(\text T\) 中的两个不同节点。如果 \(a\)\(b\) 在树上的距离不超过某个给定常数 \(x\),那么称“ \(a\)\(b\) 彼此彼此”。

给定一棵 \(n\) 个节点的有根树 \(\text T\),节点的编号为 \(1\)\(n\),根节点为 \(1\) 号节点。
你需要回答 \(q\) 个询问,询问给定两个整数 \(p\)\(k\),问有多少个有序三元组 \((a,b,c)\) 满足:

  1. \(a,b,c\)\(\text T\) 中三个不同的点,且 \(a\)\(p\) 号节点;
  2. \(a\)\(b\) 都比 \(c\) 更为厉害;
  3. \(a\)\(b\) 彼此彼此。这里彼此彼此中的常数为给定的 \(k\)

数据范围:

\(n\le 3*10^5\)

Solution:

话说之前暑假的时候貌似就见过这题,当时它貌似叫“谈笑风生”。

事先声明:本文中的 \(dep\) 是在根节点的深度为1的基础上定义的,同时,我将使用 \(S(x)\) 表示点 x 的子树
首先我们来思考一下那些点会产生贡献:

拿样例来看,对于询问 (2,2):合法的三元组有 \((2,1,4)\)\((2,1,5)\)\((2,4,5)\)

我们先重新描述一下贡献:我们发现三元组中的 \(a\) , \(b\) 并无区别,所以我们假设 (a,b,c) 的深度是单调递增的

不难看出其实我们可以把贡献拆为两部分:以点 \(p\) 做为三元组中的 \(b\) 的贡献和以点 \(p\) 作为 \(a\) 的贡献

我们先求以点 \(p\) 做为三元组中的 \(b\) 的贡献:
在这种情况下,(fa[p]->1) 路径上的所有点都可以作为 \(a\) ,\(p\) 的子树内的所有节点都可以作为 \(c\) ,因此,该部分的贡献为:
\(min(dep[p]-1,k)*(siz[p]-1)\)

然后对于以点 \(p\) 作为 \(a\) 的贡献:
假设我们已经在点 p 的子树内钦定了一个点 \(q\) 作为 \(b\) ,那么 \(c\) 就应该从 \(q\) 的子树内进行选取,也就是说,这部分的贡献是:

\[\sum_{q\in{S(p)}|dis(p,q)\in[1,k]} siz[q]-1 \]

我们不难想到用线段树合并来维护这个式子,我们以\(dep[x]\) 为下标 \(siz[x]-1\) 为点权建立一颗权值线段树,然后向上合并,那么对于每个点 \(p\) 上能取到的贡献就是 \(dep\in[dep_p,dep_p+k]\) 这段区间的总和

然后说一些细节:

由于是线段树合并,所以如果想要在线做这道题的话在 merge 的时候一定要新建一个节点作为合并的结果,否则就会使得一个点上挂有同层其他节点的贡献,这样显然是错误的

但是我们发现本题可以离线,所以我们将每个询问挂到点上,我们在构建完一个点的线段树后直接查询,在其他节点乱入之前完成答案统计。

Code:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/867816.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BurpSuite实操之解码器功能使用

解码器是一个进行手动执行或对应用程序数据者智能解码编码的工具。此功能可用于解码数据找回原来的数据形式,或者进行编码和数据加密。由解码选项(Decode as)、编码选项(Encode as)、散列(Hash)构成.。编码、解码选项,目前支持URL、HTML、Base64、ASCI、十六进制、八进制、二…

sqoop--官方首页

https://sqoop.apache.org/

md学习DAY1

Markdown学习DAY1 标题 三级标题 四级标题 字体 粗体hello,world! 斜体hello,world! 斜体加粗hello,world! 废除hello,world! 引用选择疯狂包,成为包上包分割线图片超链接 点击跳转到疯狂包子的博客 列表A B CA B C表格姓名 性别 出生代码 public

CheeseTools:红队内网横向

免责声明 仅限用于技术研究和获得正式授权的攻防项目,请使用者遵守《中华人民共和国网络安全法》,切勿用于任何非法活动,若将工具做其他用途,由使用者承担全部法律及连带责任,作者及发布者不承担任何法律连带责任项目介绍 这个库是基于已经存在的MiscTool制作的,所以非常…

2025 最新中国铁路路线地图 All In One

2025 最新中国铁路路线地图 All In One 中国铁路 12306 网站2025 最新中国铁路路线地图 All In One中国铁路 12306 网站高铁线路图中国高速铁路线路图 / 中国高铁线路规划图https://crh.gaotie.cn/ demosC3035 复 上海南 -> 亳州南 07:45 ~ 12:34 (04:49) 当日到达站序 站名…

JAVA-Day 12:方法的定义和调用

方法的定义和调用 方法定义的格式: public static void 方法名(){方法体(就是打包起来的代码)} 方法调用的格式: 方法名(); 定义调用一个方法用于个人介绍 public static void main(String[] args){myself(); } public static void myself(){System.out.println("小王同学…

PC电脑屏幕实时翻译工具-Translumo

点击上方蓝字关注我 前言 Translumo是基于.Net开发的、开源屏幕翻译器软件,它可以实时检测并翻译屏幕上所选区域中出现的文本,可检测视频中的字幕或图片中出现文字等 安装环境 [名称]:Translumo [大小]:500MB [版本]:0.9.6 [语言]:简体中文 [安装环境]:Windows 界面使用…

Text1-综合练习5

Text-综合练习5 产生十个1-100之间的随机数存入数组 求和 求平均数 找出有几个数字比平均值小 Random number1=new Random();Scanner number2=new Scanner(System.in);System.out.println("请输入要产生随机数的个数:");int n=number2.nextInt();int arr[]=new int […

Text1-综合练习6

Text-综合练习6 键盘录入n个数字,倒放他们的顺序 例如:输入1 2 3 4 5,输出5 4 3 2 1 Scanner EX=new Scanner(System.in);String arr[]=new String[100];String temp;int count=0;System.out.println("请输入要交换的数字:,以空格结束");for (int i = 0; i < 1…

Text1-综合练习2

Text-综合练习2 键盘录入一个大于2的整数,求它的平方根 结果省去小数部分保留整数 Scanner st=new Scanner(System.in);System.out.println("请输入一个大于2的整数:");int number1=st.nextInt();for(int i=1;i<number1;i++){//从1开始查找一直到number1的值int n…

Text1-综合练习1

Text1-综合练习1 逢七过 游戏规则:从任意一个数字开始报数 当你要报的数字包含七或者是七的倍数时都要说过 需求:使用程序在控制台打印出1-100之间满足逢七过规则的数 for(int i=1;i<=100;i++){if(i/10%10==7||i%10==7||i%7==0){//判断十位、个位有没有七,这个数是否能被七…

ciscn_2019_n_8 1

checksec一下能发现开了很多保护,吓人一跳,但其实我们分析一下发现只要var[13]为17就可以了if ( *(_QWORD *)&var[13] )#判断var[13]开始的8字节(_QWORD表示64位,即8字节)内存区域是否非零。*(_QWORD *)&var[13]是将var[13]的地址转换为_QWORD(64位整数)指针,然…