CF1527D MEX Tree

CF1527D MEX Tree

MEX Tree - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

文章目录

  • CF1527D MEX Tree
    • 题目大意
    • 基本思路
    • 询问
    • 修改
    • code

题目大意

给出一棵 n n n 个点的树,点从 0 0 0 n − 1 n - 1 n1 编号。定义一条路径的权值是路径上所有点编号的 m e x mex mex 。对于每个 0 ≤ i ≤ n 0\le i\le n 0in 求出 m e x mex mex i i i 的路径有几条。注意,这里统计的路径需要包括至少一条边。

一个集合的 m e x mex mex 定义为最小的不在集合中的非负整数。

基本思路

观察发现,我们在处理 i i i 时, 0 → i − 1 0\to i - 1 0i1 必须在一条路径上,否则后面的答案就都是 0 0 0

s z i sz_i szi 表示以 i i i 为根的子树大小

s p sp sp 表示非 0 0 0 端点所在对于 0 0 0 的对应子树大小

下面会要用到倍增求 l c a lca lca

我们就可以搞一种类似于虚树操作的做法。

这里假设 0 0 0 是根

询问

所以询问可以分成 3 3 3 种情况:

  • i i i 在当前的路径中
  • i i i 是当前路径端点的子孙
  • i i i 不属于上面的情况

然后 m e x = 0 mex = 0 mex=0 m e x = 1 mex = 1 mex=1 是特殊处理一下

m e x = 0 mex = 0 mex=0 时:

只要不经过 0 0 0 的路径都满足条件

所以答案就是 0 0 0 的所有子树里面任意选两个点的路径

m e x = 1 mex = 1 mex=1 时:

n n n 个点里面任意选两个点的方案数 − - m e x = 0 mex = 0 mex=0 的方案数

LL gs (LL x) { return x * (x - 1) / 2; }
void pre_ans () {ans[1] = gs (sz[0] - sz[1]);int y;for (int i = hd[0] ; i ; i = e[i].nt) {y = e[i].to;ans[0] += gs (sz[y]);int lca = Lca (y , 1);if (lca == y) ans[1] -= gs (sz[y] - sz[1]);else ans[1] -= gs (sz[y]);}
}

现在我们把其他询问分成两种情况

两个端点都不为 0 0 0,两个端点分别为 x , y x , y x,y

  • i i i 在路径上 $lca(x , i) =i \or lca (y , i) = i $

    答案就是 0 0 0

  • i i i 是当前路径端点的子孙 KaTeX parse error: Undefined control sequence: \or at position 17: …ca (x , i) = x \̲o̲r̲ ̲lca (y , i) = y

    答案就是对于端点子树大小 − - s z i sz_i szi 再乘上另一端子树大小

  • 否则,答案就是 s z x ∗ s z y sz_x * sz_y szxszy

有一个点为 0 0 0 的情况,另一个端点是 x x x

  • i i i 在当前路径中 l c a ( x , i ) = i lca (x , i) = i lca(x,i)=i

    答案就是 0 0 0

  • i i i 是当前路径端点的子孙

    i i i 是不为零的那个端点的子孙 l c a ( x , i ) = x lca (x , i) = x lca(x,i)=x,那么答案就是: ( s i z [ x ] − s i z [ i ] ) ∗ ( s i z [ 0 ] − s p ) (siz[x] - siz[i]) * (siz[0] - sp) (siz[x]siz[i])(siz[0]sp)

    i i i 0 0 0 的子孙 l c a ( x , i ) = 0 lca (x , i) = 0 lca(x,i)=0 ,那么答案就是: ( s i z [ 0 ] − s p − s i z [ i ] ) ∗ s i z [ x ] (siz[0] - sp - siz[i]) * siz[x] (siz[0]spsiz[i])siz[x]

  • i i i 不属于上面的任意一种情况

    那么 i i i 就是当前路径的分叉,那么答案就是: ( s i z [ 0 ] − s p ) ∗ s i z [ x ] (siz[0] - sp) * siz[x] (siz[0]sp)siz[x]

LL gt_ans (int x) {int lca1 = Lca (x , l) , lca2 = Lca (x , r);LL ans1 , ans2;if (r) {ans1 = sz[l] , ans2 = sz[r];if (lca1 == x || lca2 == x) return 0;else if (lca1 == l) ans1 -= sz[x];else if (lca2 == r) ans2 -= sz[x];}else {ans1 = sz[l] , ans2 = sz[r] - sp;if (lca1 == x || lca2 == x) return 0;else if (lca1 == l) ans1 -= sz[x];else if (lca1 == 0) ans2 -= sz[x];}return ans1 * ans2;
}

修改

尝试将 i i i 加入当前路径中

1、两端都不为 0 0 0

  • i i i 已经在路径上了 KaTeX parse error: Undefined control sequence: \or at position 17: …ca (x , i) = i \̲o̲r̲ ̲lca (y , i) = i

    就不用管了

  • i i i 是其中一端的子孙 $lca(x , i) = x \or lca (y , i) = y $

    直接把那个端点设为 i i i 就好了

  • 如果不属于上面的两种情况

    那么就是分叉,直接下面的答案都为 0 0 0 就好了

2、至少有一端是 0 0 0 的情况

  • 如果两端都是 0 0 0

    直接把一端设为 i i i

  • i i i 已经在路径上了 l c a ( x , i ) = i lca (x , i) = i lca(x,i)=i

    不用管了

  • l c a ( x , i ) = x lca (x , i) = x lca(x,i)=x

    x = i x = i x=i

  • 不属于上面的情况

    1、分叉 l c a ( x , i ) ≠ 0 lca (x , i)\neq 0 lca(x,i)=0 插入失败

    2、 x ≠ 0 x \neq 0 x=0 l c a ( x , i ) = 0 lca (x , i) = 0 lca(x,i)=0 ,那么 y = i y = i y=i

bool add (int x) {int lca1 = Lca (l , x) , lca2 = Lca (r , x);if (r) {if (lca1 == l) {l = x;return 1;}else if (lca1 == x) return 1;if (lca2 == r) {r = x;return 1;}else if (lca2 == x) return 1;}else {if (lca1 && (lca1 != l && lca1 != x)) return 0;else if (lca1 == l ) {l = x;return 1;}else if (lca1 == x) return 1;else if (lca1) return 0;else {r = x;return 1;}}return 0;
}

code

#include <bits/stdc++.h>
#define fu(x , y , z) for(int x = y ; x <= z ; x ++) 
#define fd(x , y , z) for(int x = y ; x >= z ; x --)
#define LL long long
using namespace std;
const int N = 6e5 + 5 , inf = 2e5;
int n , sz[N] , hd[N] , cnt , fa[N] , sp , dep[N] , f[N << 1][30] , l , r;
LL tw[30] , ans[N] , lg2[inf + 5];
struct E {int to , nt;
} e[N << 1];
void add (int x , int y) { e[++cnt].to = y , e[cnt].nt = hd[x] , hd[x] = cnt; }
int Lca (int x , int y) {int flg;while (dep[x] != dep[y]) {flg = 0;if (dep[x] > dep[y]) swap (x , y);fd (i , 25 , 0) {while (dep[f[y][i]] > dep[x]) {y = f[y][i];flg = 1;}}if (!flg) break;}while (dep[x] != dep[y]) {if (dep[x] > dep[y]) swap (x , y);y = f[y][0];}while (x != y) {flg = 0;fd (i , 25 , 0) {while (f[x][i] != f[y][i]) {x = f[x][i] , y = f[y][i];flg = 1;}}if (!flg) break;}while (x != y)x = f[x][0] , y = f[y][0];return x;
}
void dfs1 (int x) {int y;sz[x] = 1;for (int i = hd[x] ; i ; i = e[i].nt) {y = e[i].to;if (fa[x] == y) continue;fa[y] = x;dep[y] = dep[x] + 1;dfs1 (y);sz[x] += sz[y];}
}
void gt_f () {fu (i , 0 , n - 1) fu (j , 1 , 25) f[i][j] = 0;dep[0] = 1;dfs1 (0);fu (i , 0 , n - 1) f[i][0] = fa[i];fu (j , 1 , 25) {fu (i , 0 , n - 1) {f[i][j] = f[f[i][j - 1]][j - 1];}}
}
LL gs (LL x) { return x * (x - 1) / 2; }
void pre_ans () {ans[1] = gs (sz[0] - sz[1]);int y;for (int i = hd[0] ; i ; i = e[i].nt) {y = e[i].to;ans[0] += gs (sz[y]);int lca = Lca (y , 1);if (lca == y) ans[1] -= gs (sz[y] - sz[1]);else ans[1] -= gs (sz[y]);}
}
bool add (int x) {int lca1 = Lca (l , x) , lca2 = Lca (r , x);if (r) {if (lca1 == l) {l = x;return 1;}else if (lca1 == x) return 1;if (lca2 == r) {r = x;return 1;}else if (lca2 == x) return 1;}else {if (lca1 && (lca1 != l && lca1 != x)) return 0;else if (lca1 == l ) {l = x;return 1;}else if (lca1 == x) return 1;else if (lca1) return 0;else {r = x;return 1;}}return 0;
}
LL gt_ans (int x) {int lca1 = Lca (x , l) , lca2 = Lca (x , r);LL ans1 , ans2;if (r) {ans1 = sz[l] , ans2 = sz[r];if (lca1 == x || lca2 == x) return 0;else if (lca1 == l) ans1 -= sz[x];else if (lca2 == r) ans2 -= sz[x];}else {ans1 = sz[l] , ans2 = sz[r] - sp;if (lca1 == x || lca2 == x) return 0;else if (lca1 == l) ans1 -= sz[x];else if (lca1 == 0) ans2 -= sz[x];}return ans1 * ans2;
}
int main () {tw[0] = 1ll;fu (i , 1 , 25) tw[i] = 1ll * tw[i - 1] * 2;int T , u , v;scanf ("%d" , &T);while (T --) {scanf ("%d" , &n);cnt = 0;fu (i , 0 , n) ans[i] = hd[i] = fa[i] = 0;fu (i , 0 , n) fu (j , 0 , 25) f[i][j] = -1;fu (i , 1 , n - 1) {scanf ("%d%d" , &u , &v);add (u , v) , add (v , u);}gt_f ();pre_ans ();for (int i = hd[0] ; i ; i = e[i].nt) {if (Lca (e[i].to , 1) == e[i].to) {sp = sz[e[i].to];break;}}l = r = 0;fu (i , 2 , n) {if (!add (i - 1)) break;if (i == n) {ans[i] = 1;break;}ans[i] = gt_ans (i);}fu (i , 0 , n)printf ("%lld " , ans[i]);printf ("\n");}return 0;
}

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

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

相关文章

安装Zookeeper

ZooKeeper是一个开源的分布式协调服务&#xff0c;它主要用于解决分布式系统中的一致性、可靠性和协调性等问题。 选择版本 去archive.apache.org/dist/zookeeper/&#xff0c;选择Zookeeper版本&#xff0c;我选择3.4.6 上传服务器 复制地址&#xff0c;通过wget下载 wget…

400电话申请办理:为企业提供高效沟通的必备工具

在当今竞争激烈的商业环境中&#xff0c;企业需要与客户保持紧密联系&#xff0c;提供高效沟通渠道。而400电话作为一种便捷的客服热线&#xff0c;成为越来越多企业的首选。本文将介绍400电话的申请办理过程&#xff0c;帮助企业了解如何获得这一重要的沟通工具。 首先&#…

MySQL常用脚本

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《ELement》。&#x1f3af;&#x1f3af; &#x1…

asp.net core在其他程序集获取HttpContext

首先在Program.cs中&#xff0c;注册 builder.Services.AddHttpContextAccessor();Program.cs完整代码&#xff1a; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Text.Encodings.Web; using System.Text.Unicode; us…

史上最强,Jmeter性能测试-性能场景设计实例(详全)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、性能测试需求 …

微信小程序支持h5实现webrtc h264 h265低延迟传输渲染

微信小程序自成体系&#xff0c;自身也带了很强的rtc音视频能力&#xff0c;但是他捆绑了他自己的服务&#xff0c;开发也相对受限于他的api。基于以前的了解可以采webview的方式内嵌h5网址来实现自定义的webrtc.但实践起来并不轻松&#xff0c;主要是小程序的严格限制&#xf…

微信页面公众号页面 安全键盘收起后键盘下方页面留白

微信浏览器打开H5页面和公众号页面&#xff0c;输入密码时调起安全键盘&#xff0c;键盘收起后 键盘下方页面留白 解决办法&#xff1a; 1、&#xff08;简单&#xff09;只有在调起安全键盘&#xff08;输入密码&#xff09;的时候会出现这种情况&#xff0c;将input属性改为n…

如何在Next.js中使用react-viewer图片预览

1.安装依赖 使用npm&#xff0c;或者pnpm进行包安装依赖包 npm i react-viewer # or pnpm add react-viewer2.封装依赖包组件 将依赖包引入到文件之中&#xff0c;然后封装成组件&#xff0c;以备后面业务逻辑中使用&#xff1b;其示例代码如下&#xff1a; import { FC, mem…

Hadoop分布式集群搭建教程

目录 前言环境准备一、创建虚拟机二、虚拟机网络配置三、克隆虚拟机四、Linux系统配置五、Hadoop的部署配置六、Hadoop集群的启动Bug解决参考文章 前言 大数据课程需要搭建Hadoop分布式集群&#xff0c;在这里记录一下搭建过程 环境准备 搭建Haoop分布式集群所需环境&#x…

kafka属性说明

kafka中关于一些字段说明 groupId :标识消费者分组id&#xff0c;如果多个消费者id相同&#xff0c;就表示这几个消费者是一组&#xff0c;当一组多个消费者消费同一个topic时&#xff0c;一组中只会有一个成功消费 代码如下 这时只会有一条消息被消费

【科学文献计量】利用pybibx分析Scopus文献数据集(EDA,N-Grams,Cluster,Network analysis,NLP)

利用pybibx分析Scopus文献数据集 1 运行前准备1.1 数据集1.2 前置库2 加载库3 数据导入4 探索式数据分析,即EDA4.1 表格可视化4.2 词云图可视化4.3 N-Grams可视化4.4 文献聚类4.5 主题词演化4.6 桑基图可视化4.7 树图可视化4.8 作者生产力可视化5 网络可视化5.1 文献引用与被引…

自行开发一个安卓相册的功能说明

手机本身附带相册&#xff0c;为什么还要自己开发啊&#xff1f;我也不想啊。这不是事情要求吗&#xff1f;为了整理思路&#xff0c;把自己想到的功能点汇总起来&#xff1a; 初步要求照片、视频分开游览。将来版本再看是否合并。打开时&#xff0c;使用上次的路径。如果有文…

轻松搭建个人web站点:OpenWRT教程结合内网穿透技术实现公网远程访问

&#x1f525;博客主页&#xff1a; 小羊失眠啦 &#x1f516;系列专栏&#xff1a; C语言、Linux &#x1f325;️每日语录&#xff1a;山不让尘&#xff0c;川不辞盈。 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前言 uhttpd 是 OpenWrt/LuCI 开发者从零开始编写的 Web …

视频美颜SDK,提升企业视频通话质量与形象

在今天的数字时代&#xff0c;视频通话已经成为企业与客户、员工之间不可或缺的沟通方式。然而&#xff0c;由于网络环境、设备性能等因素的影响&#xff0c;视频通话中的画面质量往往难以达到预期效果。为了提升视频通话的质量与形象&#xff0c;美摄美颜SDK应运而生&#xff…

【C语言】预处理详解

前言 在上一篇博客中&#xff0c;我们了解了代码是如何执行的&#xff0c;简单介绍了编译中预处理步骤&#xff0c;在这篇博客中我们将详细了解预处理。 文章目录 一、预定义符号二、#define定义2.1 定义常量2.2 定义宏2.3 创建代码片段 三、#和##运算符3.1 字符串化操作符#3.2…

python关联分析实践学习笔记

曾经有个沃尔玛超市&#xff0c;它将啤酒与尿布这样两个奇怪的东西放在一起进行销售&#xff0c;并且最终让啤酒与尿布这两个看起来没有关联的东西的销量双双增加。 我们关注的是在这样的场景下&#xff0c;如何找出物品之间的关联规则。接下来就来介绍下如何使用Apriori算法&…

RabbitMQ与springboot整合

1、基本概念 Server&#xff1a;接收客户端的连接&#xff0c;实现AMQP实体服务&#xff1b;Connection&#xff1a;连接&#xff0c;应用程序与Server的网络连接&#xff0c;TCP连接&#xff1b;Channel&#xff1a;信道&#xff0c;消息读写等操作在信道中进行。客户端可以建…

读书笔记-《ON JAVA 中文版》-摘要26[第二十三章 注解]

文章目录 第二十三章 注解1. 基本语法1.1 基本语法1.2 定义注解1.3 元注解 2. 编写注解处理器2.1 编写注解处理器2.2 注解元素2.3 默认值限制 3. 使用javac处理注解4. 基于注解的单元测试5. 本章小结 第二十三章 注解 注解&#xff08;也被称为元数据&#xff09;为我们在代码…

【Overload游戏引擎细节分析】从视图投影矩阵提取视锥体及overload对视锥体的封装

overoad代码中包含一段有意思的代码&#xff0c;可以从视图投影矩阵逆推出摄像机的视锥体&#xff0c;本文来分析一下原理 一、平面的方程 视锥体是用平面来表示的&#xff0c;所以先看看平面的数学表达。 平面方程可以由其法线N&#xff08;A, B, C&#xff09;和一个点Q(x0,…

让 Visual Studio 用上 ChatGPT

一、简介 Visual chatGPT Studio 是 Visual Studio 的一个免费扩展&#xff0c;它直接在 IDE 中添加了 chatGPT 功能。它允许用户以可以根据菜单功能的方式使用 chatGPT。 二、功能介绍 该扩展提供了一组使用 ChatGPT 命令&#xff0c;可以在编辑器中选择你需要处理的代码或…