[NOISG2022 Qualification] Dragonfly Solution in O(d log d)

news/2025/1/10 21:41:39/文章来源:https://www.cnblogs.com/dccy/p/18664766

[NOISG2022 Qualification] Dragonfly Solution in O(d log d)

提供一个使用线段树合并、栈、树状数组的严格单 \(\log\) 离线做法。

题目大意:给你一棵树,每个点有权值和颜色,每次问你一个从 \(1\) 开始的路径,求权值不为 \(0\) 的节点的颜色种类数,并且把所有权值不为 \(0\) 的节点权值减一,询问之间不独立。

解题思路:考虑离线下来,因为一个节点权值为 \(0\) 后就没有贡献了,那么考虑求出最后能产生贡献的时刻 \(t_i\)

那么能吃节点 \(i\) 的询问在 \(i\) 的子树内。考虑以时间为下标建线段树,询问就在这个询问所在的时间插入一个点,那么我们可以自底向上线段树合并,合并到点 \(i\) 时在线段树上二分即可求出 \(t_i\)。这一部分的线段树只需维护一个子树大小。这一部分是 \(O(d\log d)\) 的。

求出 \(t_i\) 后,对于第 \(j\) 个询问,我们就是求满足下列条件的颜色个数:从 \(1\)\(h_j\) 路径上存在这种颜色的点 \(i\) 使得 \(t_i\ge j\)

考虑从根开始遍历,进入一个节点就插入这个节点的贡献,离开子树就撤销贡献。

我们现在就想知道从 \(1\) 到当前点的路径上,每种颜色 \(t\) 的最大值是多少。然后每次最大值更新时用数据结构维护一下即可。

由于如果存在颜色相同的 \(i,j\) 满足 \(i\)\(j\) 的祖先,且 \(t_i\ge t_j\),那么 \(j\) 是没有用的。所以考虑对每种颜色开一个栈,当 \(t\) 大于栈顶时才推进栈中,然后用一个以 \(t\) 为下标的树状数组维护:有多少种颜色的 \(t\) 大于等于某个数。

这一部分也是 \(O(d\log d)\) 的。

然后就做完了,最终的复杂度就是 \(O(d\log d)\) 的(这里我们设 \(n,d\) 同阶)。

实现细节

注意到线段树合并时,我们动态开点的静态数组可能会 MLE。但是线段树合并时很多合并后的节点就扔掉了。考虑用一个 vector 回收节点即可。

另外注意 \(n,d\) 的规模是不一样的,数组不要开小了。

AC 代码

const int N=2e5+5,M=2e6+5,L=2e7;
int tot,ls[L],rs[L],sz[L],rt[N];
vi emp;
#define mid ((l+r)>>1)
void merge(int &x,int y,int l,int r) {if(!x) {x=y; return;}if(!y) {return;}if(l==r) {sz[x]+=sz[y]; return;}merge(ls[x],ls[y],l,mid),merge(rs[x],rs[y],mid+1,r);sz[x]=sz[ls[x]]+sz[rs[x]];emp.pb(y);
}
void add(int &x,int l,int r,int y) {if(!x) {if(tot<L-1) x=++tot;else x=Back(emp),emp.pop_back(),sz[x]=ls[x]=rs[x]=0;}if(l==r) {sz[x]++; return;}if(y<=mid) add(ls[x],l,mid,y);else add(rs[x],mid+1,r,y);sz[x]=sz[ls[x]]+sz[rs[x]];
}
int query(int x,int l,int r,int y) {if(l==r) return l;if(sz[ls[x]]>=y) return query(ls[x],l,mid,y);return query(rs[x],mid+1,r,y-sz[ls[x]]);
}
struct BIT{#define lowbit(x) (x&(-x))int s[M];void update(int x,int y) {while(x<M) s[x]+=y,x+=lowbit(x);}int query(int x){int _s=0;while(x) _s+=s[x],x-=lowbit(x);return _s;}
}bit;
vi g[N],q[N];
int n,Q;
int b[N],s[N],h[M],t[N];
void dfs1(int x,int y) {for(int v:g[x]) {if(v==y) continue;dfs1(v,x);merge(rt[x],rt[v],1,Q);}for(int v:q[x]) add(rt[x],1,Q,v);if(b[x]) {if(sz[rt[x]]<b[x]) t[x]=Q;else t[x]=query(rt[x],1,Q,b[x]);}
}
stack<int> mx[N];
int ans[M];
void solve(int x,int y){int co=s[x],flag=0;if(t[x]) {if(mx[co].empty()||t[x]>mx[co].top()) {if(Size(mx[co])) bit.update(M-mx[co].top(),-1);mx[co].push(t[x]);bit.update(M-t[x],1);flag=1;}}for(int v:q[x]) {ans[v]=bit.query(M-v);}for(int v:g[x]) {if(v==y) continue;solve(v,x);}if(flag) {bit.update(M-t[x],-1);mx[co].pop();if(Size(mx[co])) bit.update(M-mx[co].top(),1);}
}
signed main(){read(n,Q);fo(i,1,n) read(b[i]);fo(i,1,n) read(s[i]);fo(i,1,Q) read(h[i]),q[h[i]].pb(i);fu(i,1,n) {int u,v; read(u,v);g[u].pb(v),g[v].pb(u);}dfs1(1,0);solve(1,0);fo(i,1,Q) write(ans[i],' ');return 0;
}

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

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

相关文章

BurpSuite实操之重发器功能使用

手动操作来触发单独的HTTP请求,并进行应用程序响应的工具,此功能用于根据不同的情况修改和发送相后的请求并分析,通过调整Request的参数,不断尝试,通过Response查看状态,从而节省在浏览器中操作的时间。 在渗透测试过程中,我们经常使用Repeater进行请求与响应的消息验证…

G1原理—3.G1是如何提升垃圾回收效率

大纲 1.G1为了提升GC的效率设计了哪些核心机制 2.G1中的记忆集是什么 3.G1中的位图和卡表 4.记忆集和卡表有什么关系 5.RSet记忆集是怎么更新的 6.DCQ机制的底层原理是怎样的 7.DCQS机制及GC线程对DCQ的处理提升G1垃圾回收器GC效率的黑科技 G1设计了一套TLAB机制 + 快速分配机制…

1.10日学习笔记之C++的类

类其实就是一种数据类型,和结构相似。类的成员包括两类,属性(成员变量)和行为(成员函数)。 成员函数定义的两种方法(可能有多种,觉得这两种比较常用) 1、将类的成员函数定义在类体内,如 class CPerson {public: short age;short getage(){return age;}};2、将类的成…

着火智能监测识别摄像机

着火智能监测识别摄像机利用了先进的图像处理技术和人工智能算法,能够快速、准确地检测环境中的着火点,从而及时采取必要的安全措施。其工作原理如下:首先,摄像机配备高清摄像头,能够实时捕捉并传输环境图像。这些图像通过内置的处理单元,进行高效处理和分析。其次,利用…

BurpSuite实操之测试器功能

对web应用程序进行自动化攻击。此功能有多种用途,如漏洞利用、模糊测试、进行暴力pojie等1、目标设置代理发送过来请求的目标主机及端口信息。 输入要攻击的目标及端口2、位置设置在这个模块可以设置攻击的参数,及攻击使用的类型(1)Sniper-狙击手(2)Battering ram-破城锤…

采沙船智能监测识别摄像机

采沙船智能监测识别摄像机还支持数据记录和分析功能,可以生成详尽的非法采沙统计报告和趋势分析,为河流管理决策提供科学依据。管理部门可以通过监控系统的数据分析,制定精准的禁采政策和优化河流资源管理,有效保护水域生态环境,防止非法采砂对生态系统的破坏。在实际应用…

C api简单查询需要的几步

C api查询简单需要的几步 1.准备sql语句 2.绑定变量 通过sqlstatement类bindout方法将查询出来的值与存储他们的变量绑定。 这里绑定是为了以后从结果集中提取一行时只需要一行就可以完成将提取出 来的变量赋值。 3.执行execute 在这一步将sql语句执行。在这里有几个重点 mysql…

iterm2

外观 这个github上的项目提供了很多主题 https://iterm2colorschemes.com/ 亮色主题感觉还可以的几个: OneHalfLight、BuiltinLight、BlulocoLight、Materil、ProLight、Tango Half Adapted 下面截图是基于 Tango Half Adapted用蓝色代替青色,黄色加深之后的效果(vim括号插件…

22. MDI窗口设计

一、什么是MDI窗口MDI 窗口(Multiple-Document Interface),又称多文档界面,它主要用于同时显示多个文档,每个文档显示在各自的窗口中。MDI 窗口中通常包含子菜单和窗口菜单,用于在窗口或文档之间进行切换。用 QMainWindow 建立的主界面,通常会同时建立或打开多个相互独立…

详解:订单履约系统规划

大家好,我是汤师爷~ 什么是订单履约系统? 订单履约是从消费者下单支付到收到商品的全流程管理过程,包括订单接收、订单派单、库存分配、仓储管理和物流配送等环节,核心目标是确保商品准时、准确地送达消费者手中。 通过订单履约系统,消费者可以实时了解商品的物流状态和预…

文件单独编译生成

编译设备树也最好在 source过的那个窗口中来编译错误提示如下: 同时在makefile文件修改时也要注意

In‐band Network Telemetry

#卫星 #遥测技术 #INT 一、INT是什么? INT,In‐band Network Telemetry ,带内网络遥监测。telemetry,英文原意是遥测技术。从其英文名称可以了解如下: a.In-band,说明监测指令及数据均在带内传输 b.telemetry ,说明是长距离,远程获取网络数据的方法。 想象一下卫星在…