【动态维护树的直径】【HBCPC2023】I. Colorful Tree

题目

在这里插入图片描述
https://codeforces.com/gym/105139/problem/I

思路

其实相当于是分别求黑色点和白色点所构成的树的直径。
当两个连通块连在了一起,假设它们的直径是 ( u 1 , v 1 ) , ( u 2 , v 2 ) (u_1,v_1),(u_2,v_2) (u1,v1)(u2,v2),那么新连通块的直径一定是 ( u 1 , v 1 ) , ( u 2 , v 2 ) , ( v 1 , u 2 ) , ( v 1 , v 2 ) , ( u 1 , u 2 ) , ( u 1 , v 2 ) (u_1,v_1),(u_2,v_2),(v_1,u_2),(v_1,v_2),(u_1,u_2),(u_1,v_2) (u1,v1)(u2,v2)(v1,u2)(v1,v2)(u1,u2)(u1,v2) 中的一条。
由于题目要给链染色,所以只能树剖+线段树维护。
白色的点倒过来求一遍即可。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+7;
vector<int> dep,fa,ans,siz,top,mxs,dfn,f,id,tr,tag,ti;
vector<array<int,3>> d;
int n,q,inf,tot;
vector<array<int,2>> Q;
vector<vector<int>> e,p;
int gf(int x)
{return x==fa[x]?x:fa[x]=gf(fa[x]);
}
void dfs1(int u,int fa)
{siz[u]=1;dep[u]=dep[fa]+1;f[u]=fa;for(auto v:e[u]){if(v==fa) continue;dfs1(v,u);siz[u]+=siz[v];if(siz[v]>siz[mxs[u]])mxs[u]=v;}
}
void dfs2(int u,int topf)
{dfn[u]=++tot; id[tot]=u;top[u]=topf;if(!mxs[u]) return;dfs2(mxs[u],topf);for(auto v:e[u]){if(v==f[u]||v==mxs[u]) continue;dfs2(v,v);}
}
int lca(int x,int y)
{while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]) swap(x,y);x=f[top[x]];}if(dep[x]<dep[y]) swap(x,y); return y;
}
int getdis(int u,int v)
{int l=lca(u,v);return dep[u]+dep[v]-2*dep[l]+1;
}
void pushdown(int u)
{if(!tag[u]) return;tag[u<<1]=tag[u<<1|1]=tag[u];tr[u<<1]=tr[u<<1|1]=tag[u];tag[u]=0;
}
void build(int u,int st,int ed)
{if(st==ed){tr[u]=inf;return;}int mid=st+ed>>1;build(u<<1,st,mid); build(u<<1|1,mid+1,ed);
}
void change(int u,int st,int ed,int l,int r,int t)
{if(l<=st&&ed<=r){tag[u]=t;tr[u]=t;return;}pushdown(u);int mid=st+ed>>1;if(mid>=l) change(u<<1,st,mid,l,r,t);if(mid<r) change(u<<1|1,mid+1,ed,l,r,t);
}
int query(int u,int st,int ed,int x)
{if(st==ed&&ed==x){return tr[u];}pushdown(u);int mid=st+ed>>1;if(mid>=x) return query(u<<1,st,mid,x);else return query(u<<1|1,mid+1,ed,x);
}
void dye(int x,int y,int c)
{while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]) swap(x,y);change(1,1,n,dfn[top[x]],dfn[x],c);x=f[top[x]];}if(dep[x]<dep[y]) swap(x,y); change(1,1,n,dfn[y],dfn[x],c);
}
int merge(int u,int v)
{int x=gf(u),y=gf(v);if(x==y) return 0;auto [u1,v1,d1]=d[x];auto [u2,v2,d2]=d[y];int ur=u1,vr=v1,dr=d1;if(d2>d1){ur=u2; vr=v2; dr=d2;}u=u1; v=u2; int di=getdis(u,v);if(di>dr){ur=u; vr=v; dr=di;}u=u1; v=v2; di=getdis(u,v);if(di>dr){ur=u; vr=v; dr=di;}u=v1; v=u2; di=getdis(u,v);if(di>dr){ur=u; vr=v; dr=di;}u=v1; v=v2; di=getdis(u,v);if(di>dr){ur=u; vr=v; dr=di;}d[x]={ur,vr,dr};fa[y]=x;return dr;
}
void init(int n,int q)
{tot=0;dep.clear(); dep.resize(n+1);fa.clear(); fa.resize(n+1);f.clear(); f.resize(n+1);id.clear(); id.resize(n+1);tr.clear(); tr.resize(n<<2|1);tag.clear(); tag.resize(n<<2|1);for(int i=1; i<=n; i++) fa[i]=i;e.clear(); e.resize(n+1);p.clear(); p.resize(q+2);ti.clear(); ti.resize(n+1);siz.clear(); siz.resize(n+1);top.clear(); top.resize(n+1);mxs.clear(); mxs.resize(n+1);dfn.clear(); dfn.resize(n+1);ans.clear(); ans.resize(q+1);Q.clear(); Q.resize(q+1);
}
void O_o()
{cin>>n>>q;inf=q+1;init(n,q);for(int i=1; i<n; i++){int x,y;cin>>x>>y;e[x].push_back(y);e[y].push_back(x);}dfs1(1,0);dfs2(1,1);build(1,1,n);d.resize(n+1);for(int i=1; i<=n; i++)d[i]={i,i,1};for(int i=1; i<=q; i++){int u,v;cin>>u>>v;Q[i]={u,v};}for(int i=q; i>=1; i--){auto [u,v]=Q[i];dye(u,v,i);}for(int i=1; i<=n; i++){int t=query(1,1,n,dfn[i]);ti[i]=t;p[t].push_back(i);}//solveint mx=1;for(int i=1; i<=q; i++){for(auto u:p[i]){for(auto v:e[u]){if(ti[v]>i) continue;int ass=merge(u,v);mx=max(mx,ass);
//				cerr<<ass<<"**\n\n";}}ans[i]=max(ans[i],mx);}mx=1;for(int i=1; i<=n; i++)d[i]={i,i,1};for(int i=1; i<=n; i++) fa[i]=i;for(int i=q+1; i>=2; i--){for(auto u:p[i]){for(auto v:e[u]){if(ti[v]<i) continue;int ass=merge(u,v);mx=max(mx,ass);
//				cerr<<ass<<"**\n\n";}}ans[i-1]=max(ans[i-1],mx);}for(int i=1; i<=q; i++){cout<<ans[i]<<"\n";}
}
signed main()
{ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);cout<<fixed<<setprecision(2);int T=1;cin>>T;while(T--){O_o();}
}

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

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

相关文章

一个开源的工具类轮子是怎么造出来的

心路历程 为什么要做 在22年9月的某一天&#xff0c;在公司开需求评审时&#xff0c;接到了一个给PDF、图片添加水印的需求。做为一个刚工作的CURD程序员&#xff0c;在遇到这些问题时&#xff0c;第一反应是去github上找找有没有类似的开源框架。但是&#xff0c;出乎我意料…

2024年 电工杯 (B题)大学生数学建模挑战赛 | 大学生平衡膳食食谱的优化设计 | 数学建模完整代码解析

DeepVisionary 每日深度学习前沿科技推送&顶会论文&数学建模与科技信息前沿资讯分享&#xff0c;与你一起了解前沿科技知识&#xff01; 本次DeepVisionary带来的是电工杯的详细解读&#xff1a; 完整内容可以在文章末尾全文免费领取&阅读&#xff01; 问题1&…

快手二面准备【面试准备】

快手二面准备【面试准备】 前言版权快手二面准备秋招一面中的问题实习一面中的问题计算机网络和操作系统论坛项目登录注册ThreadLocal代替session存储用户秒杀项目登录注册->阿里验证码->rpcsession为什么改为token实现&#xff0c;redis存储用户信息由binlog的用法->…

Python魔法学院:PySpider篇——网络世界的探险与征服

Hi&#xff0c;我是阿佑&#xff0c;迎来到Python魔法学院&#xff0c;今天阿佑要带大家学习的是PySpider篇——一门让你在网络世界中探险与征服的魔法课程。从环境搭建到高级功能应用&#xff0c;再到性能优化&#xff0c;每一个章节都是成为数据大师的必经之路&#xff01; 文…

为什么拼命赚钱:穷怕了

我内心深处比较自卑。 从小在农村长大&#xff0c;爸不管妈不爱。 这么说大家没感觉&#xff0c;从小什么都干&#xff0c;六岁开始做饭&#xff0c;每次开学都会全员大扫除&#xff0c;站在那里脚踩泥土地、眼神呆滞、双手无处安放、眼神都不敢直视的小伙子就是我&#xff0…

JavaScript Window对象

一、BOM&#xff08;浏览器对象模型&#xff09; window对象是一个全局对象&#xff0c;也可以说是JavaScript中的顶级对象。 像document、alert()、console.log()这些都是window的属性&#xff0c;基本BOM的属性和方法都是window的。 所有通过var定义在全局作用域中的变量、…

四川古力科技抖音小店,创新科技点亮购物新体验

在这个数字化浪潮汹涌的时代&#xff0c;四川古力科技以其前瞻性的战略眼光和创新能力&#xff0c;闪耀于抖音小店这片电商新蓝海&#xff0c;开启了未来购物的新纪元。作为一家集技术研发、产品创新、市场营销于一体的科技型企业&#xff0c;古力科技不仅为消费者带来了前所未…

idea中显示git的Local Changes

1. 第一打开idea中的Settings文件 2. 找到Version Contro中的commint 3. 取消勾选应用即可 4. 本地提交就会显示出来

Google Earth Engine(GEE)深度学习入门教程-Python数据读入篇

Python数据读入篇 前置条件&#xff1a; GEE预处理影像导出保存为tfrecord的数据包&#xff0c;并下载到本地tensorflow的深度学习环境 本篇文章的目的主要是把Tfrecord格式的数据加载为tf可使用的数据集格式 设定超参数 首先需要设定导出时的波段名称和数据格式&#xff…

ARTS Week 30

Algorithm 本周的算法题为 747. 至少是其他数字两倍的最大数 给你一个整数数组 nums &#xff0c;其中总是存在 唯一的 一个最大整数 。 请你找出数组中的最大元素并检查它是否 至少是数组中每个其他数字的两倍 。如果是&#xff0c;则返回 最大元素的下标 &#xff0c;否则返回…

SpringBoot集成Logback将日志写入文件夹

一、logback简介&#xff1a; 目前比较常用的ava日志框架:Logback、log4j、log4j2、JUL等等。 Logback是在log4j的基础上重新开发的一套日志框架&#xff0c;是完全实现SLF4J接口API(也叫日志门面)。 Logback 的架构非常通用&#xff0c;可以应用于不同的环境。目前logback分为…

LeetCode题练习与总结:从前序与中序遍历序列构造二叉树--105

一、题目描述 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,9,20,nul…

什么是经典蓝牙模块?

什么是经典蓝牙模块&#xff1f;   前面我们已经就蓝牙模块的概念做了了解&#xff0c;随着时间的推移&#xff0c;产品越来越智能&#xff0c;需要的蓝牙模块也就越来越广泛&#xff0c;本篇文章我们就一起了解下什么是经典蓝牙模块。   经典蓝牙模块(BT)泛指支持蓝牙协议…

SwiftUI中的手势(DragGesture拖拽手势及Drag动画组件)

上一篇文章我们了解了如何使用.gesture修饰符和GestureState属性包装器&#xff0c;让我们看看另一种常见的手势&#xff1a;DragGesture拖拽手势。 下面先看个效果图&#xff1a; 这个效果中&#xff0c;我们实现了一个Text文本&#xff0c;并添加了拖拽手势&#xff0c;可以…

Flutter Text导致A RenderFlex overflowed by xxx pixels on the right.

使用Row用来展示两个Text的时候页面出现如下异常,提示"A RenderFlex overflowed by xxx pixels on the right." The following assertion was thrown during layout: A RenderFlex overflowed by 4.8 pixels on the right.The relevant error-causing widget was:…

【仿RabbitMQ消息队列项目day2】使用muduo库中基于protobuf的应用层协议进行通信

一.什么是muduo? muduo库是⼀个基于非阻塞IO和事件驱动的C高并发TCP网络编程库。 简单来理解&#xff0c;它就是对原生的TCP套接字的封装&#xff0c;是一个比socket编程接口更好用的编程库。 二.使用muduo库完成一个英译汉翻译服务 TranslateServer.hpp: #pragma once #in…

MyBatis中Where标签:揭秘高效SQL构建的秘密

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 理解Where标签的基础概念 在MyBatis中&#xff0c;<where>标签是用于构建SQL查询语句中的一个非常重要的元素。它允许你在一个动态的SQL语句中添加WHERE子句&#xff0c;而不需要担心SQL语法错误或额外的逗号…

如何利用51建模网,实现3D模型线上展示和应用?

按照下面的步骤&#xff0c;在51建模网上传3D模型&#xff0c;并编辑完成后&#xff0c;接下来就是如何让这些3D模型得到更好的展示、传播和应用。 一、3D内容快速分享与传播 3D模型在51建模网上传发布后&#xff0c;即可获得一个可分享的链接和二维码&#xff0c;直接分享给客…

20240520解决在Ubuntu20.04下编译RK3588的Android12的SDK出现C2_GIT_BUILD_VERSION未定义的问题

20240520解决在Ubuntu20.04下编译RK3588的Android12的SDK出现C2_GIT_BUILD_VERSION未定义的问题 2024/5/20 20:19 缘起&#xff1a;通过./repo/repo/repo sync -l得到的SDK正常&#xff0c;但是解压缩之后的SDK却出错了&#xff01; 通过grep很容易发现有三个地方有&#xff0c…

PointCloudLib 点云投影到XOY平面功能实现 C++版本

0.实现效果 左图为原始点云,右图为投影到XOY平面上的点云 将三维的点云投影到二维平面,方便处理一些二维轮廓方面的计算。 可以投影到空间中任意平面上。 1.算法原理 原理 点云投影是将三维空间中的点云数据映射到一个二维平面上的过程。这通常通过以下步骤实现: 确定投…