首页 > 其他分享 >[HEOI2014]大工程 题解

[HEOI2014]大工程 题解

时间:2024-04-20 20:33:23浏览次数:22  
标签:sz limits 工程 int 题解 uson HEOI2014 dp dis

发现可以直接建立虚树。

设 \(dp_{u,0/1/2}\) 表示第 \(u\) 个节点的子树内,所有选中节点到它的距离之和/选中节点中到它的最短距离/选中节点中到它的最长距离,\(as_{u,0/1/2}\) 则代表对于这个子树,题目所问问题的三个答案,\(i1,i2\) 分别为使 \(dp_{u,1/2}\) 取极值的 \(v\)。

则 \(dp\) 方程为:

\[dp_{u,0}=\sum\limits_{v\in uson}dis(u,v)\times sz_v+dp_{0,v} \]

\[dp_{u,1}=\min\limits_{v\in uson}dp_{v,1}+dis(u,v) \]

\[dp_{u,2}=\max\limits_{v\in uson}dp_{v,2}+dis(u,v) \]

\[as_{u,0}=\sum\limits_{v\in uson}as_{v,0}+(dis(u,v)\times sz_v+dp_{v,0})(sz_x-sz_y) \]

\[as_{u,1}=\min(\min\limits_{v\in uson}as_{v,1},\min\limits_{v\in uson且i1\ne v}dp_{u,1}+dp_{v,1}+dis(u,v)) \]

\[as_{u,2}=\max(\max\limits_{v\in uson}as_{v,2},\max\limits_{v\in uson且i2\ne v}dp_{u,2}+dp_{v,2}+dis(u,v)) \]

时间复杂度 \(O(\sum k\log k)\)。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1000005;
int n,l,q,dfn[N],fa[N][21],p[N],a[N];
int m,r,t,k,h[N],nxt[N*2],to[N*2];
int d[N],nex[N*2],go[N*2],dep[N],b[N*2];
ll dp[3][N],as[3][N],c[N*2],sz[N];
int cmp(int x,int y){
	return dfn[x]<dfn[y];
}void ad(int x,int y){
	to[++m]=y;nxt[m]=h[x];h[x]=m;
}void add(int x,int y,int z){
	go[++r]=y;c[r]=z;
	nex[r]=d[x];d[x]=r;
}void dfs(int x,int f){
	dep[x]=dep[f]+1;
	fa[x][0]=f;dfn[x]=++l;
	for(int i=0;i<20;i++)
		fa[x][i+1]=fa[fa[x][i]][i];
	for(int i=h[x];i;i=nxt[i])
		if(f!=to[i]) dfs(to[i],x);
}int lca(int x,int y){
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=20;~i;i--)
		if(dep[x]-dep[y]>=(1<<i))
			x=fa[x][i];
	if(x==y) return x;
	for(int i=20;~i;i--)
		if(fa[x][i]!=fa[y][i])
			x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}int dis(int x,int y){
	return dep[x]+dep[y]-2*dep[lca(x,y)];
}void dp_(int x,int f){
	ll i1=0,i2=0;
	as[1][x]=1e18;
	if(p[x]==2) sz[x]=1;
	else dp[1][x]=1e18;
	for(int i=d[x];i;i=nex[i]){
		int y=go[i];
		if(y==f) continue;
		dp_(y,x);sz[x]+=sz[y];
		dp[0][x]+=c[i]*sz[y]+dp[0][y];
		if(dp[1][x]>dp[1][y]+c[i])
			dp[1][x]=dp[1][y]+c[i],i1=y;
		if(dp[2][x]<dp[2][y]+c[i])
			dp[2][x]=dp[2][y]+c[i],i2=y;
	}if(p[x]==2) as[2][x]=dp[2][x];
	for(int i=d[x];i;i=nex[i]){
		int y=go[i];if(y==f) continue;
		as[0][x]+=as[0][y]+(c[i]*sz[y]+dp[0][y])*(sz[x]-sz[y]);
		as[1][x]=min(as[1][y],as[1][x]);
		as[2][x]=max(as[2][y],as[2][x]);
		if(i1!=y)
			as[1][x]=min(as[1][x],dp[1][x]+dp[1][y]+c[i]);
		if(i2!=y)
			as[2][x]=max(as[2][x],dp[2][x]+dp[2][y]+c[i]);
	}
}int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1,x,y;i<n;i++)
		cin>>x>>y,ad(x,y),ad(y,x);
	dfs(1,0);
	cin>>q;while(q--){
		cin>>k;
		for(int i=1;i<=k;i++)
			cin>>a[i],b[++t]=a[i],p[a[i]]=2;
		sort(a+1,a+k+1,cmp);
		for(int i=1;i<k;i++){
			int x=lca(a[i],a[i+1]);
			if(!p[x]) p[x]=1,b[++t]=x;
		}sort(b+1,b+t+1,cmp);
		for(int i=1;i<t;i++){
			int lc=lca(b[i],b[i+1]);
			add(lc,b[i+1],dep[b[i+1]]-dep[lc]);
			add(b[i+1],lc,dep[b[i+1]]-dep[lc]);
		}int rt=lca(b[1],b[2]);dp_(rt,0);
		cout<<as[0][rt]<<" "<<as[1][rt]<<" "<<as[2][rt]<<"\n";
		for(int i=1;i<=t;i++){
			p[b[i]]=sz[b[i]]=d[b[i]]=0;
			dp[0][b[i]]=dp[1][b[i]]=dp[2][b[i]]=0;
			as[0][b[i]]=dp[1][b[i]]=as[2][b[i]]=0;
		}for(int i=1;i<=r;i++)
			nex[i]=go[i]=c[i]=0;
		r=t=0;
	}return 0;
}

标签:sz,limits,工程,int,题解,uson,HEOI2014,dp,dis
From: https://www.cnblogs.com/chang-an-22-lyh/p/18148118/heoi2014_dagongcheng_tj

相关文章

  • [题解] [洛谷 P1174] 打砖块
    [洛谷P1174]打砖块题目描述有\(n\)行\(m\)列的砖块和\(k\)发子弹,每个砖块都有一个得分,每次可以用一发子弹打碎某一列最下面的砖块并得到相应的得分。有的砖块在打碎后可以获得一发额外子弹的奖励。求该游戏的最大得分。输入格式第一行有\(3\)个正整数,\(n,m,k\)。......
  • [题解] [洛谷 P1174] 打砖块
    [洛谷P1174]打砖块题目描述有\(n\)行\(m\)列的砖块和\(k\)发子弹,每个砖块都有一个得分,每次可以用一发子弹打碎某一列最下面的砖块并得到相应的得分。有的砖块在打碎后可以获得一发额外子弹的奖励。求该游戏的最大得分。输入格式第一行有\(3\)个正整数,\(n,m,k\)。......
  • newstartweek3部分题解
    64位利用格式化字符串修改got表例题:newstartweek3putorsystem老规矩先checksec和代码审计:看到开了canary和NX(但是对于这道题的话canary是没有用的),然后源码这边也没有发现有system函数,也没有后门函数,所以我们需要自己在libc里面找,然后就有bin/sh那么我们就只用把got表里......
  • 建立STM32 工程
    新建工程步骤建立工程文件夹,在keil中建立工程,选择型号在工程文件夹中建立Start,Library,User等文件夹,复制固件库里的文件到工程文件夹在工程里对应建立Start,Library,User等同名称分组,然后将文件添加到工程分组里工程选项,C/C++,includepaths内声明包含头文件的文件夹工程选项,C/......
  • 掌握时间序列特征工程:常用特征总结与 Feature-engine 的应用
    时间序列数据的特征工程是一种技术,用于从时间序列数据中提取信息或构造特征,这些特征可用于提高机器学习模型的性能。以下是一些常见的时间序列特征工程技术:滚动统计量:计算时间窗口内的统计量,如平均值、中位数、标准偏差、最小值和最大值。这些统计量可以捕捉到时间序列在不同时......
  • [BZOJ3037] 创世纪 题解
    基环内向树上dp,不过在这里提供给一种非典型做法。考虑将环上的每一条边都断开,这样就会形成多棵树,先在这些树上进行树形\(dp\)。设\(dp_{i,0/1}\)表示不选/选\(i\)时,\(i\)子树内的最大选点数。明显方程为:\[\begin{cases}dp_{u,0}=\sum\limits_{v\inuson}\max(dp_{v,0},dp......
  • [题解]ABC209F Deforestation
    ABC209FDeforestation首先我们可以思考\(a_i\)和\(a_{i+1}\)先砍哪棵花费少。可以看出,当\(a[i]<a[i+1]\)时,先砍\(a[i+1]\),反之亦然。所以这个题转化成了:给定\(n-1\)个关系,分别表示\(n\)个值中相邻两个的大小关系,问满足这些关系的序列个数。与AtcoderEducationalDPContest......
  • φ(* ̄0 ̄)3337. poj1845 sumdiv题解
    遇到数论题就要推式子!提供最美丽的latex\[a^b=p_1^{a_1*b}*p_2^{a_2*b}*p_3^{a_3*b}......*p_n^{a_n*b}\\那么他的因数之和为:\\({p_1}^0+{p_1}^1+...+{p_1}^{a_1*b})\\*({p_2}^0+{p_2}^1+...+{p_2}^{a_2*b})\\...\\*({p_n}^0+{p_n}^1+...+{p_n}^{a_n*b})\\=>利用等......
  • 「NOIP2012」同余方程 题解!!
    嗨嗨嗨!又是我想写这道题,我们就需要掌握:拓展欧几里得顾名思义,它就是欧几里得算法(人话:辗转相除法)的proMax版本别告诉我你不会辗转相除法拓展欧几里得的作用是求对于方程\[a*x+b*y=gcd(a,b)\]解出x,y的值。让我们一步步分析!贴个辗转相除板子先:voidojld(inta,intb){ i......
  • poj3696 The Luckiest number 题解
    很容易想到,\(n\)个8可以转换为\((10^{n+1}-1)/9*8\)容易你个集贸啊,xzz推10分钟我推了一个上午顺便膜拜xzz然后就是推式子了。。。(悲\[(10^{n+1}-1)/9*8\equiv0\pmodh\\=>{10^{n+1}*8-8\above1pt9}\equiv0\pmodh\\=>10^{n+1}*8-8\equiv0\pmod{9h}\\=>10^{n+1}*8\e......