bzoj3611: [Heoi2014]大工程

局部路径规划算法 - B样条曲线(B-spline Curves) 本文详解了B样条以及代码实现 阅读详情

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3611

思路:构建虚树DP

首先这种题有一个特征,就是所有询问的总点数是O(n)的

那么就可以考虑对每次询问建一棵虚树,再在虚树上DP。

那么我们对于每次询问,就不一定要把整棵树建出来,而是只要管一部分点即可

比如u,v两点之间没有其他询问点,那么我们就可以把uv直接连起来,中间的点是什么我们并不关心。

我们只要建出这样一棵树即可:只含当前询问点和它们的lca,并且相对位置关系不变

举个例子:原树是这样的,假如选了1、5、8、10号节点


构建出来的虚树就是:

怎样构建虚树?

先对原图做一边dfs预处理,得出dfn和一些乱七八糟的东西。

对于每次询问,先把所有询问点按dfn排序,一个一个插入。

我们要用栈维护一个叫“最右链”的东西,就是最右边的一条链...

每次和最右链的最深的一个点求lca,并动态维护之。

如果栈为空,直接加进栈,

否则求出栈顶元素stk[top]和当前点的lca

如果dfn[lca]<dfn[stk[top]],那就一直弹栈直到dfn[lca]>=dfn[stk[top]],因为这些点都不会在新的最右链里。

(记得特判lca是否已在栈中)

看图直观理解就是左边的点与当前点求lca不会贡献出新的点,所以只用管最右链即可



这样我们每次就可以O(m)的构建虚树了,这也是为什么这些题都有Σq[i]<=O(n)的限制。

用虚树还要满足一个条件,就是要维护的信息

例如,和,最大,最小,都有类似于前缀和的性质,

就是我们可以从v(u的后代)直接求出u的答案,而不需要遍历u到v的所有边

否则虚树就没有降低复杂度,因为每次还是要在原树上走。


对于这题,剩下的只有在虚树上treeDP了。

记录f[i]表示在i的子树中的路径总长,siz[i]表示i的子树中询问点的个数

maxs[i]表示i子树中询问点到根的最长路长,mins[i]同理。

转移很显然 f[i]=f[son[i]]+siz[son[y]]*(cnt-siz[son[y]])*dis(i,son[i])   (cnt是此次询问总点数)

对于maxs[i]

如果i是询问点,那就只要在子树中找另一个询问点即可

即我们可以直接用maxs[i]更新答案。

否则我们要找两个点,用maxs[i]+maxs[son[i]]+dis(i,son[i])更新答案

最小同理


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long ll;
const int maxn=1000010,maxm=maxn<<1,maxk=23,inf=1e9;
using namespace std;
int n,q,dis[maxn],dfn[maxn],tim,dep[maxn],fa[maxn][maxk],num,poi[maxn];
int stk[maxn],top,siz[maxn],maxs[maxn],mins[maxn],ans1,ans2;
ll f[maxn];bool bo[maxn];
bool cmp(int a,int b){return dfn[a]<dfn[b];}
struct Tgraph{
	int pre[maxm],now[maxn],son[maxm],tot;
	void add(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
	void dfs1(int x){
		dfn[x]=++tim;
		for (int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
		for (int y=now[x];y;y=pre[y]) if (son[y]!=fa[x][0])
			dis[son[y]]=dis[x]+1,dep[son[y]]=dep[x]+1,fa[son[y]][0]=x,dfs1(son[y]);
	}
	void dfs2(int x){
		siz[x]=bo[x],maxs[x]=0,mins[x]=inf,f[x]=0;
		for (int y=now[x];y;y=pre[y]){
			int d=dis[son[y]]-dis[x];
			dfs2(son[y]),siz[x]+=siz[son[y]];
			ans1=min(ans1,mins[x]+mins[son[y]]+d),mins[x]=min(mins[x],mins[son[y]]+d);
			ans2=max(ans2,maxs[x]+maxs[son[y]]+d),maxs[x]=max(maxs[x],maxs[son[y]]+d);
			f[x]+=f[son[y]]+1ll*siz[son[y]]*(num-siz[son[y]])*d;
		}
		if (bo[x]) ans1=min(ans1,mins[x]),ans2=max(ans2,maxs[x]),mins[x]=0;
		now[x]=0;
	}
}g1,g2;

int lca(int a,int b){
	if (dep[a]<dep[b]) swap(a,b);
	for (int h=dep[a]-dep[b],i=20;i>=0;i--) if (h>=(1<<i)) h-=(1<<i),a=fa[a][i];
	if (a==b) return a;
	for (int i=20;i>=0;i--) if (fa[a][i]!=fa[b][i]) a=fa[a][i],b=fa[b][i];
	return fa[a][0];
}

void work(){
	top=0;
	for (int i=1;i<=num;i++){
		if (!top){stk[++top]=poi[i];continue;}
		int u=lca(stk[top],poi[i]);
		while (dfn[u]<dfn[stk[top]]){
			if (dfn[u]>=dfn[stk[top-1]]){
				g2.add(u,stk[top]);
				if (stk[--top]!=u) stk[++top]=u;
				break;
			}
			g2.add(stk[top-1],stk[top]),top--;
		}
		stk[++top]=poi[i];
	}
	while (top>1) g2.add(stk[top-1],stk[top]),top--;
	ans1=inf,ans2=0,g2.dfs2(stk[1]);
	printf("%lld %d %d\n",f[stk[1]],ans1,ans2);
	for (int i=1;i<=num;i++) bo[poi[i]]=0;g2.tot=0;
}

int main(){
	scanf("%d",&n);
	for (int i=1,a,b;i<n;i++) scanf("%d%d",&a,&b),g1.add(a,b),g1.add(b,a);
	g1.dfs1(1),scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d",&num);
		for (int j=1;j<=num;j++) scanf("%d",&poi[j]),bo[poi[j]]=1;
		sort(poi+1,poi+1+num,cmp),work();
	}
	return 0;
}


文档信息抽取技术:从非结构化文本到结构化信息的旅程 文档信息抽取技术是一种将非结构化文本转化为结构化信息的技术。这种技术可以从各类文档中自动提取出如实体、关系和其他重要信息,并将它们转化为方便计算机进一步处理和分析的格式。 阅读详情

相关推荐

单细胞测序流程(十)KEGG通路富集分析与可视化圈图实战解析

本文详细解析了单细胞测序数据分析中KEGG通路富集分析与可视化圈图的完整实战流程。从差异表达基因列表出发,通过R语言进行KEGG富集分析,并利用Perl脚本进行基因ID转换,最终使用GOplot包绘制高级可视化圈图,帮助研究者将基因列表转化为有意义的生物学故事。

i7j8k9l的博客 406

2019 HEOI游记(真-退役记)

\(\color{#00ffff}{DAY \ \ -1}\) 下午又在说无聊的注意事项,有点紧张,不想做题,只想水题233333 晚上就水了几道网络流,晚四透彻依旧,yhzr二连胜,心里倒是放松了不少 \(\color{#00ffff}{DAY \ \ 0}\) 到了北站,TM火车站每开门。。。在外面饿了一小时 有了noip 被奶凉的教训,几乎一直远离他们,然而还是被mod了一会 最后还是在德州...

weixin_30825581的博客 617

PIPE Interface解析之PIPE SerDes/Original架构

PIPI Interface;SerDes架构;Original架构;PHY Tx结构;PHY Rx结构;

weixin_45176819的博客 2606

HEOI2016解题报告

树 在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个 结点,可以打多次标记。)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖 先)你能帮帮他吗? 题解 这题如果直接做的话,就是一个裸的树链剖分。...

weixin_33724046的博客 313

Linux虚拟机mysql安装教程(详细步骤)出现了一个错误:依赖检测失败

Linux虚拟机安装mysql的详细步骤(有报错预警哦)

m0_74953387的博客 5257

vcpkg管理OpenCASCADE的5个高效技巧:从多版本共存到离线部署

本文详细介绍了使用vcpkg高效管理OpenCASCADE的5个实用技巧,包括多版本共存、性能优化、团队共享、CI/CD集成和离线部署。通过自动配置和版本控制,vcpkg显著简化了OpenCASCADE的开发环境管理,特别适合工业级CAD开发场景。

rain6的博客 187

[HEOI2014]大工程

建议将这篇博客作为【虚树入门】。

七代目鸽影 194

YOLOv11改进 | 注意力篇 | YOLOv11引入CBAM注意力机制

我们的实验表明各种模型的分类和检测性能得到了一致的改进,证明了 CBAM 的广泛适用性。简单介绍:CBAM的主要思想是通过关注重要的特征并抑制不必要的特征来增强网络的表示能力。模块首先应用通道注意力,关注"重要的"特征,然后应用空间注意力,关注这些特征的"重要位置"。到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv11改进有效涨点专栏,本专栏目前为新开的,后期我会根据各种前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

tsg6698的博客 2万+

「TJOI / HEOI2016」排序 ( 整体二分 + 线段树 )

题目链接 解题报告: 二分答案,将原串转成01串并用用线段树维护升降序排列即可。 #define first f #define second s #define ll long long #define mp make_pair #define pb push_back #define pf push_front #define lb lower_bound #define ub upper_...

qhq889的博客 211

SCSA,scCATCH,SciBet,SingleR 四种注释方法比较

以下是和四种细胞类型注释方法的详细对比,从。

qq_40256654的博客 1215

华为OD机试 - 荒岛求生 - 栈Stack(Python/JS/C/C++ 新系统 100分)

每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天优快云在线答疑。

学Java,找哪吒 2838

HEOI 2014 大工程 题解

题目传送门 题目大意: 给出一棵树,边权为 111,每次询问给出若干个关键点,问这些关键点两两之间的最长的路径、最短的路径、路径长度之和。 题解 造出虚树然后一波 dpdpdp 就做完了。 代码如下: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define maxn 1000010 #define inf 999999999 #define ll long

a_forever_dream的博客 249

五、实战pxe安装ubuntu 22.04 软raid1(实际生产pxe配置)

这段配置文件是一个cloud-init的自动安装配置,用于自动化部署Ubuntu服务器操作系统。它定义了从系统身份、键盘布局、区域设置到磁盘分区和RAID配置的一系列设置,并且包含了在安装过程的最后阶段执行的一些命令。基础设置version: 1指定了autoinstall配置文件的版本。source定义了安装源,这里是ubuntu-server。identity设置了主机名(hostname)、用户(username)和密码(password注意这里的密码是经过加密的。键盘与语言设置。

jundao1997的专栏 999

BZOJ 3611: [Heoi2014]大工程

二次联通门 :BZOJ 3611: [Heoi2014]大工程 /* BZOJ 3611: [Heoi2014]大工程 虚树 + dp 对于每次的关键点建好虚树后 考虑树形dp dp[i] 表示在以i为根的子树路径总长 size[i] 表示在以i为根的子树中关键点的个数...

weixin_30632899的博客 93

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

BZOJ3611: [Heoi2014]大工程

BZOJ3611: [Heoi2014]大工程 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上。 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 a,b 的最短路径。 现在国家有很多个计划,每个计划都是这样,我们选中了 k 个点,然后在它们两两之间 新建 C(k...

weixin_30376323的博客 82

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

bzoj3611: [Heoi2014]大工程(虚树+树形dp)

传送门 思路:考虑每次怎么做O(n)dpO(n)dpO(n)dp,直接对于每个点对的lcalcalca考虑贡献即可。 因此建出虚树然后同样对于lcalcalca考虑贡献。 代码: #include<bits/stdc++.h> #define ri register int using namespace std; const int rlen=1<<18|1; inlin...

苟为蒟蒻又何妨 268

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

bzoj3611:[Heoi2014]大工程

传送门 显然还是虚树,虚树之后树形dp 然后我没想到正确的树形dp,只想到一个错误的二次换根 写到一半发现错了,只能写了颗线段树+二次换根,线段树记的就是所有关键点到当前根的距离 写到一半又想到了正确的树形dp,然而真的不想再改了,感觉二次换根也能过: 就是每次对于当前走到的节点记一下它子树里深度最深的和深度最浅的关键点,以及深度和,然后考虑经过当前点的路径长度,更新就好了 然后还需要统计答案,所...

weixin_30952103的博客 125

BZOJ3611: [Heoi2014]大工程【虚树+树形DP】

3611: [Heoi2014]大工程 首先我们肯定会想到DP求这个答案,但是发现点数实在太多,然后建虚树就可以了。 #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=1e6+5; typ...

XSamsara的博客 AFO 273

BZOJ 3611:Heoi2014 大工程

原来最长链用的都是两边dfs求直径或用两个数组存最长链和次长链,今天学习了,如果只需要求出直径大小,别的什么都不用,那么只用一个数组进行dp更加方便。 void DP(int u) { //f2[u]:最短链 f3[u]:最长链 if (vis[u]) f1[u]=1,f2[u]=0,f3[u]=0; else f1[u]=0,f2[u]=1e18,f3[u]=-1e18; for ...

Love_xyh的博客 219

BZOJ3611: [Heoi2014]大工程【虚树】

题目描述: 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。 我们这个国家位置非常特殊,可以看成是一个边权为1的树,城市位于顶点上。 在 2 个国家 a,b 之间建一条新通道需要的代价为树上 a,b 的路径长度。 现在国家有很多个计划,每个计划都是这样,我们选中了 k 个点,然后在它们两两之间 新建 C(k,2)条 新通道。 现在对于每个计划,我们想知道: 1.这些新通道的代价和 2....

Master.Yi的博客 172

bzoj 3611: [Heoi2014]大工程

Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上。  在 2 个国家 a,b 之间建一条新通道需要的代价为树上 a,b 的最短路径。  现在国家有很多个计划,每个计划都是这样,我们选中了 k 个点,然后在它们两两之间 新建 C(k,2)条 新通道。 现在对于每个计划,我们想知道

lqybzx的专栏 407

BZOJ 3611: [Heoi2014]大工程 虚树 树形dp

3611: [Heoi2014]大工程Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1927  Solved: 797[Submit][Status][Discuss]Description国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上。 在 2 个国家 a,b 之...

BlackJack 448

BZOJ 3611: [Heoi2014]大工程 虚树Dp

title BZOJ 3611 LUOGU 4103 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上。 在 \(2\) 个国家 \(a,b\) 之间建一条新通道需要的代价为树上 \(a,b\) 的最短路径。 现在国家有很多个计划,每个计划都是这样,我们选中了 \(k\) 个点,然...

dilu0653的博客 167
上一篇: bzoj3571: [Hnoi2014]画框
下一篇: bzoj2286: [Sdoi2011]消耗战
thy_asdf
博客等级 码龄12年 16粉丝 186原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值