【题解】JZOJ6703 tree

题意

给定 n n n 个点的树,每个点有点权,每次询问点权大于等于 x x x 的点构成的子图有多少个连通块,动态修改点权,保证修改后点权不小于修改前。

题解

首先有一个显然的结论:森林的连通块个数 = 点数 - 边数。

这就是说,对于一个询问 x x x,我们只需要知道大于等于 x x x 的点有多少个,所连两点均大于等于 x x x 的边有多少条,就能算出答案。

考虑动态维护大于等于 x x x 的点,发现这是一个单点修改区间查询,用一个统计后缀和的树状数组即可,每次修改就在原来的权值处减 1 1 1,在新的权值处加 1 1 1。查询 [ x , W m a x ] [x,W_{max}] [x,Wmax] 的和即可。

考虑怎么维护边。同样用一个树状数组统计所连接两点大于等于 x x x 的边。一条边的贡献显然是 min ⁡ ( a u , a v ) \min(a_u,a_v) min(au,av)

考虑 sub3,也就是菊花图。显然叶子节点的修改直接在树状数组上修改即可。对于根节点 1 1 1,开一个 multiset 维护大于等于 a 1 a_1 a1 的邻接点。对于 multiset 里面的点,其贡献显然是 a 1 a_1 a1,其它的点贡献就是 a x a_x ax。时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)

考虑将这个做法拓展至每个点。每个点开 multiset s x s_x sx,存它的儿子里大于等于它的点。

对于一个修改 a x ← y a_x\larr y axy,考虑其儿子 s o n son son

  • a s o n < a x a_{son}<a_x ason<ax s o n son son 修改前后都不在 s x s_x sx 中,边 ( x , s o n ) (x,son) (x,son) 的贡献一直是 a s o n a_{son} ason
  • a s o n ≥ a x , a s o n < y a_{son}\ge a_x,a_{son}<y asonax,ason<y s o n son son 原本在 s x s_x sx 中,修改后不在,边 ( x , s o n ) (x,son) (x,son) 的贡献由 a x a_x ax 变为 a s o n a_{son} ason
  • a s o n ≥ y a_{son}\ge y asony s o n son son 修改前后都在 s x s_x sx 中,边 ( x , s o n ) (x,son) (x,son) 的贡献由 a x a_x ax 变为 y y y

考虑其父亲 f a fa fa

  • y < a f a y<a_{fa} y<afa x x x 修改前后都不在 s f a s_{fa} sfa 中,边 ( f a , x ) (fa,x) (fa,x) 的贡献由 a x a_x ax 变为 y y y
  • a x < a f a , y ≥ a f a a_x<a_{fa},y\ge a_{fa} ax<afa,yafa x x x 修改前不在 s f a s_{fa} sfa 中,修改后在 s f a s_{fa} sfa 中,边 ( f a , x ) (fa,x) (fa,x) 的贡献由 a x a_x ax 变为 a f a a_{fa} afa
  • a x ≥ a f a a_x\ge a_{fa} axafa x x x 修改前后都在 s f a s_{fa} sfa 中,边 ( f a , x ) (fa,x) (fa,x) 的贡献一直是 a f a a_{fa} afa

按照以上维护 s x s_x sx 和树状数组即可。

容易发现,所有节点的 multiset 的大小总和一定是递减的。将一个点 x x x 提升 d d d 后,若想让 x x x 再次加入 multiset,需要把 [ a x , a x + d ] [a_x,a_x+d] [ax,ax+d] 的点全部修改才能做到。所以这个修改均摊 O ( 1 ) O(1) O(1)。总时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)

实现

这个树状数组的写法比较奇妙,是统计后缀和的。

注意不要漏了一些修改。

#include <bits/stdc++.h>
using namespace std;
#define fre(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
template<typename Ty> void read(Ty &x) {int c = getchar(), f = 1;for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = -1;for (x = 0; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);x *= f;
}
#define lowbit(x) x & (-x)
const int N = 500005, W = 1000005;
int n, q, a[N], cnt = 0, fir[N], nxt[N << 1], to[N << 1], fa[N], tr[W], trp[W];
multiset<int> s[N];
void ade(int u, int v) {cnt++, nxt[cnt] = fir[u], fir[u] = cnt, to[cnt] = v;cnt++, nxt[cnt] = fir[v], fir[v] = cnt, to[cnt] = u;
}
void upd(int x, int val) { for (; x; x -= lowbit(x)) tr[x] += val; }
int gsum(int x) {int sum = 0;for (; x < W; x += lowbit(x)) sum += tr[x];return sum;
}
void updp(int x, int val) { for (; x; x -= lowbit(x)) trp[x] += val; }
int gsump(int x) {int sum = 0;for (; x < W; x += lowbit(x)) sum += trp[x];return sum;
}
void dfs(int r) {for (int i = fir[r]; i; i = nxt[i])if (to[i] != fa[r]) {fa[to[i]] = r, dfs(to[i]);if (a[to[i]] >= a[r]) s[r].insert(a[to[i]]);else upd(a[to[i]], 1);}
}
int main() {fre(tree);read(n), read(q);for (int i = 1; i <= n; i++) read(a[i]), updp(a[i], 1);for (int i = 1, u, v; i < n; i++) read(u), read(v), ade(u, v);dfs(1);for (int i = 1; i <= n; i++)if (!s[i].empty())upd(a[i], s[i].size());for (int t = 1, opt, x, y; t <= q; t++) {read(opt);if (opt == 1) {read(x), read(y);if (fa[x]) {if (a[x] >= a[fa[x]]) s[fa[x]].erase(s[fa[x]].find(a[x]));else upd(a[x], -1), upd(min(y, a[fa[x]]), 1);if (y >= a[fa[x]]) s[fa[x]].insert(y);}int cn = 0;while (!s[x].empty() && *s[x].begin() < y) upd(*s[x].begin(), 1), s[x].erase(s[x].begin()), cn++;upd(a[x], -cn), upd(a[x], -s[x].size()), upd(y, s[x].size()), updp(a[x], -1), updp(a[x] = y, 1);}else read(x), printf("%d\n", gsump(x) - gsum(x));}return 0;
}

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

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

相关文章

LeetCode 332. Reconstruct Itinerary【欧拉回路,通路,DFS】困难

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

Vue3+ElementUI使用

<!DOCTYPE html> <html> <head><meta charset"UTF-8"><meta name"viewport" content"initial-scale1.0,maximum-scale1.0,minimum-scale1.0,user-scalable0, widthdevice-width"/><!-- 引入样式 --><lin…

【C++】list的模拟实现【完整理解版】

目录 一、list的概念引入 1、vector与list的对比 2、关于struct和class的使用 3、list的迭代器失效问题 二、list的模拟实现 1、list三个基本函数类 2、list的结点类的实现 3、list的迭代器类的实现 3.1 基本框架 3.2构造函数 3.3 operator* 3.4 operator-> 3…

JavaScript 基础 - 第1天笔记

JavaScript 基础 - 第1天 了解变量、数据类型、运算符等基础概念&#xff0c;能够实现数据类型的转换&#xff0c;结合四则运算体会如何编程。 体会现实世界中的事物与计算机的关系理解什么是数据并知道数据的分类理解变量存储数据的“容器”掌握常见运算符的使用&#xff0c;了…

bug总结问题集和知识点集(一)

目录 一 bug问题集1. 端口被占用 二 oracle1. oracle查看版本怎么操作2. oracle数据库&#xff1a;参数个数无效![在这里插入图片描述](https://img-blog.csdnimg.cn/6a2eebc164f9406c81525371893bbd11.png)3. ORACLE数据库如何完整卸载? 三 mybatis1. mybatis用注解如何实现模…

Java手写最大子数组和算法(如Kadane算法)和最大子数组和算法(如Kadane算法)应用拓展案例

Java手写最大子数组和算法&#xff08;如Kadane算法&#xff09;和最大子数组和算法&#xff08;如Kadane算法&#xff09;应用拓展案例 1. 算法思维导图 以下是使用mermaid代码表示的Kadane算法的实现原理&#xff1a; #mermaid-svg-rI7hVAVsP1qtjZK7 {font-family:"tr…

学习Node js:raw-body模块源码解析

raw-body是什么 raw-body的主要功能是处理HTTP请求体的原始数据。它提供了以下核心功能&#xff1a; 解析请求体&#xff1a;可以从HTTP请求中提取原始数据&#xff0c;包括文本和二进制数据。配置选项&#xff1a;通过配置项&#xff0c;可以设置请求体的大小限制、编码方式…

【LeetCode-简单题KMP】232. 用栈实现队列

文章目录 题目方法一&#xff1a;用输入栈和输出栈模拟队列 题目 方法一&#xff1a;用输入栈和输出栈模拟队列 只有输出栈为空的时候才能将输入栈的元素补充到输出栈&#xff0c;否则输出栈不为空&#xff0c;如果再从输入栈往输出栈填充元素&#xff0c;就会弄乱队列的先进先…

【SpringMVC】拦截器JSR303的使用

【SpringMVC】拦截器&JSR303的使用 1.1 什么是JSR3031.2 为什么使用JSR3031.3 常用注解1.4 Validated与Valid区别1.5 JSR快速入门1.5.2 配置校验规则# 1.5.3 入门案例二、拦截器2.1 什么是拦截器2.2 拦截器与过滤器2.3 应用场景2.4 拦截器快速入门2.5.拦截器链2.6登录案列权…

合同矩阵充要条件

两个实对称矩阵合同的充要条件是它们的正负惯性指数相同。 正惯性指数是矩阵正特征值个数&#xff0c;负惯性指数是矩阵负特征值个数。 即合同矩阵的充分必要条件是特征值的正负号个数相同。 证明&#xff1a; 本论证中的所有矩阵先假设为对称矩阵&#xff0c;但不限于对称…

接口测试——接口协议抓包分析与mock_L1

目录&#xff1a; 接口测试价值与体系常见的接口协议接口测试用例设计postman基础使用postman实战练习 1.接口测试价值与体系 接口测试概念 接口&#xff1a;不同的系统之间相互连接的部分&#xff0c;是一个传递数据的通道接口测试&#xff1a;检查数据的交换、传递和控制…

设计模式之职责链模式

职责链模式:使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一个对象处理它为止。 这里发出这个请求的客户端并不知道这当中的哪一个对象最终处理这个请求&am…

ajax 中 success 方法的 return

做前后台交互时会经常用到 ajax&#xff0c;有时候会遇到这样的情况&#xff0c;我们在 a 方法中调用 b 方法&#xff0c;b 方法里是一个 ajax&#xff0c;成功请求后会返回一个结果 data&#xff0c;而我们希望通过 b 方法的返回值获取到 data&#xff0c;我们的代码可能是这样…

TCP详解之三次握手和四次挥手

TCP详解之三次握手和四次挥手 1. TCP基本认识 1.1 什么是 TCP TCP是面向连接的、可靠的、基于字节流的传输层通信协议。 1.2 TCP协议段格式 我们先来看看TCP首部协议的格式 我们先来介绍一些与本文关联比较大的字段&#xff0c;其他字段不做详细阐述。 序列号&#xff1a…

2023面试知识点一

1、新生代和老年代的比例 默认的&#xff0c;新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 )&#xff0c;即&#xff1a;新生代 ( Young ) 1/3 的堆空间大小。老年代 ( Old ) 2/3 的堆空间大小。其中&#xff0c;新生代 ( …

213. 打家劫舍 II

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;动态规划 写在最后 Tag 【动态规划】【数组】 题目来源 213. 打家劫舍 II 题目解读 你是一个专业的小偷&#xff0c;现在要偷一排屋子&#xff0c;但是你不能偷相邻的两间屋子&#xff08;这一排房子的首尾是相连的&…

什么是性能调优?方法有哪些?流程是怎样的?

一、性能调优的含义 性能调优通俗来讲就是对计算机硬件、操作系统和应用有相当深入的了解&#xff0c;调节三者之间的关系&#xff0c;实现整个系统&#xff08;包括硬件、操作系统、应用&#xff09;的性能最大化&#xff0c;并能不断的满足现有的业务需求。 在判定软件存在…

将本地构建的镜像推送到远程镜像库,构建多种系统架构支持的Docker镜像并推送到Docker Hub

目录 推送到 Docker Hub前提&#xff1a;需要在 [Docker Hub](https://hub.docker.com/) 创建账户、创建仓库。1. 创建 Dockerfile 和构建镜像&#xff1a;docker build -t2. 登录到远程镜像库&#xff1a;docker login3. 将镜像标记为远程仓库地址&#xff1a;docker tag4. 推…

Ubuntu-server 22.04LTS源码编译apache服务器

1 系统环境 # cat /etc/os-release PRETTY_NAME"Ubuntu 22.04.3 LTS" NAME"Ubuntu" VERSION_ID"22.04" VERSION"22.04.3 LTS (Jammy Jellyfish)" VERSION_CODENAMEjammy IDubuntu ID_LIKEdebian HOME_URL"https://www.ubuntu.co…

Hadoop-Hbase

1. Hbase安装 1.1 安装zookeeper、 hbase 解压至/opt/soft&#xff0c;并分别改名 配置环境变量并source生效 #ZK export ZOOKEEPER_HOME/opt/soft/zk345 export PATH$ZOOKEEPER_HOME/bin:$PATH #HBASE_HOME export HBASE_HOME/opt/soft/hbase235 export PATH$HBASE_HOME/b…