首页 > 其他分享 >[NOISG2022 Qualification] Dragonfly Solution in O(d log d)

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

时间:2025-01-10 21:43:33浏览次数:1  
标签:Dragonfly co log sz int Solution 节点 mx

[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;
}

标签:Dragonfly,co,log,sz,int,Solution,节点,mx
From: https://www.cnblogs.com/dccy/p/18664766

相关文章

  • python画大的pass与fail logo(带颜色)
    print("\033[32m"+4*""+9*"x"+10*""+1*"x"+11*""+7*"x"+5*""+7*"x"+4*""+"\033[0m")print("\033[32m"+4*""+2*"x"......
  • 使用mysqlbinlog 备份 binlog日志文件
    使用mysqlbinlog备份二进制日志文件默认情况下,mysqlbinlog读取二进制日志文件并以文本格式显示其内容。这使您能够更轻松地检查文件中的事件并重新执行它们(例如,通过将输出用作mysql的输入)。mysqlbinlog可以直接从本地文件系统读取日志文件,或者,--read-from-remote-server它可......
  • whoami who w last latlog
    [root@localhost~]#whoamiroot[root@localhost~]#w21:22:19up20min,3users,loadaverage:0.00,0.01,0.01USERTTYFROMLOGIN@IDLEJCPUPCPUWHATrootpts/0192.168.0.10721:129:550.01s0.01s-bash......
  • log4j的配置ConversionPattern详细讲解
    先写下我一直没找到的ConversionPattern里面参数代表的详细含义参数说明例子%c列出logger名字空间的全称,如果加上{<层数>}表示列出从最内层算起的指定层数的名字空间log4j配置文件参数举例输出显示媒介假设当前logger......
  • 使用Docker部署的基于binlog实现Mysql8
    概念MySQL基于Binlog的主从复制(Master-SlaveReplication)是MySQL数据库中实现数据复制的一种机制。在这种复制模式下,主库(Master)记录所有对数据库的修改操作(如INSERT、UPDATE、DELETE等)到二进制日志(Binlog),从库(Slave)则读取这些日志并执行相同的操作,从而保持与主库的数据一......
  • 基于Simulink的模糊逻辑控制(Fuzzy Logic Control, FLC)的他励直流电动机与永磁直流电动
    目录基于Simulink的模糊逻辑控制(FuzzyLogicControl,FLC)的他励直流电动机与永磁直流电动机模型实例1.项目背景2.系统架构2.1他励直流电动机简介2.2永磁直流电动机简介2.3模糊逻辑控制原理3.模型设计3.1他励直流电动机建模3.2永磁直流电动机建模3.3模糊逻......
  • webapi 集成 log4net 写入 ElasticSearch
    log4net.config<log4net><appendername="RollingLogFileAppender"type="log4net.Appender.RollingFileAppender"><!--定义文件存放位置--><filevalue="log/"/><appendToFilevalue="true"......
  • 【Apache Paimon】-- 14 -- Spark 集成 Paimon 之 Filesystem Catalog 与 Hive Catalo
    目录1.背景介绍2.环境准备2.1、技术栈说明2.2、环境依赖2.3、硬件与软件环境2.4、主要工具清单2.5、Maven项目结构2.6、mavenpom.xml依赖3.Spark与Paimon FilesystemCatalog集成3.1、HDFSFileSystemcatalog3.1.1、代码内容3.1.2、运行输出结果3.1.2.......
  • KnowledgePrompts: Exploring the Abilities of Large Language Models to Solve Prop
    本文是LLM系列文章,针对《KnowledgePrompts:ExploringtheAbilitiesofLargeLanguageModelstoSolveProportionalAnalogiesviaKnowledge-EnhancedPrompting》的翻译。KnowledgePrompts:通过知识增强提示探索大型语言模型解决比例类比的能力摘要1引言2相关......
  • 基于FPGA的直接数字频率合成器verilog实现,包含testbench
    1.算法运行效果图预览(完整程序运行后无水印)  2.算法运行软件版本vivado2019.2 3.部分核心程序(完整版代码包含详细中文注释和操作步骤视频)//sin,cos相位累加器的控制always@(posedgei_clk)//时钟上边沿触发beginif(i_rst)//系统复位 begin o_sin_......