ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P5904 [POI2014]HOT-Hotels 题解

2022-05-20 12:33:19  阅读:149  来源: 互联网

标签:leq int 题解 sum son fa HOT ans Hotels


题面

原题 \(n\leq 5000\),加强版 \(n\leq 10^5\),实际上能做 \(n\leq 10^6\)。

长链剖分。做这种很多点满足限制的题,套路差不多。设 \(f_{u,i}\) 表示 \(u\) 子树内到 \(u\) 距离为 \(i\) 的点数,\(g_{u,i}\) 表示 \(u\) 子树内的点对 \((x,y)\) 数量,满足再加一个到 \(u\) 距离为 \(i\) 的点 \(z\),\((x,y,z)\) 可以形成题目要求的三元组。

转移的式子大概长这样:

\[f_{u,i}=\sum_{v\in son(u)}f_{v,i-1} \]

\[g_{u,i}=\sum_{v\in son(u)} f_{v,i-1}\cdot f_{u,i}+\sum_{v\in son(u)} g_{v,i+1} \]

\[ans=\sum_u \big(\sum_{v\in son(u)}\sum_i f_{u,i-1}\cdot g_{v,i}+\sum_{v\in son(u)}\sum_i g_{u,i+1}\cdot f_{v,i}\big) \]

使用长剖优化,动态开内存给长链顶部,每个点直接继承重儿子信息,把轻儿子合并,复杂度 \(O(n)\)。

注意动态开内存的大小,如果有 \(-1\) 的数组,需要在前后都留下足够的空间。

点击查看代码
const int N=1e5+13;
int n,d[N],son[N];
ll buf1[N<<3],buf2[N<<4];
ll *f[N],*g[N],*nowf=buf1,*nowg=buf2;
std::vector<int> e[N];
ll ans;
void dfs(int u,int fa){
	for(auto v:e[u]){
		if(v==fa) continue;
		dfs(v,u);
		if(d[v]>d[son[u]]) son[u]=v;
	}
	d[u]=d[son[u]]+1;
}
void dp(int u,int fa){
	if(son[u]) f[son[u]]=f[u]+1,g[son[u]]=g[u]-1,dp(son[u],u);
	f[u][0]=1,ans+=g[u][0];
	for(auto v:e[u]){
		if(v==fa||v==son[u]) continue;
		f[v]=nowf,nowf+=d[v]+4;nowg+=(d[v]<<1)+10,g[v]=nowg;
		dp(v,u);
		for(int i=0;i<d[v];++i) ans+=(i?f[u][i-1]*g[v][i]:0)+g[u][i+1]*f[v][i];
		for(int i=0;i<=d[v];++i) g[u][i]+=(i?f[v][i-1]*f[u][i]:0)+(i<d[v]?g[v][i+1]:0);
		for(int i=1;i<=d[v];++i) f[u][i]+=f[v][i-1];
	}
}
int main(){
//	freopen("4.in","r",stdin);
//	freopen("P5904.out","w",stdout);
	read(n);
	for(int i=1;i<n;++i){
		int u,v;read(u),read(v);
		e[u].pb(v),e[v].pb(u);
	}
	dfs(1,0);
	f[1]=nowf,nowf+=d[1]+4;
	nowg+=(d[1]<<1)+4,g[1]=nowg;
	dp(1,0);
	println(ans);
	return 0;
}

标签:leq,int,题解,sum,son,fa,HOT,ans,Hotels
来源: https://www.cnblogs.com/winterfrost/p/p5904-solution.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有