ICode9

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

题解[P5666树的重心]

2021-10-03 10:01:43  阅读:230  来源: 互联网

标签:子树 P5666 重心 题解 mx1 leq text mx size


题目链接

题意:给定一棵树,求删去每条边后分裂成的两棵树的重心的编号和之和。

\(\text{Solution}\):

对每个点 \(x\) 分开讨论,统计有多少条边割掉后 \(x\) 能成为重心。

\(\text{Part 1}\) : 理论分析

假设让 \(x\) 成为根,其最大子树大小为 \(mx\) , 次大子树大小为 \(mx1\)

第一种情况:不在最大子树中割边

这样割后 \(x\) 的最大子树为必为 \(mx\)

设割去一个子树,其大小为 \(t\) ,则与 \(x\) 连通的树大小为 \(n-t\)

则 \(x\) 能成为重心就有 \(mx \leq \left\lfloor\frac{n-t}{2}\right\rfloor\) ,即 \(t\leq n-2mx\)

第二种情况:在最大子树中割边

割后形成的最大子树大小是 \(\max(mx1,mx-t)\)

所以有 \(\max(mx1,mx-t)\leq\left\lfloor\frac{n-t}{2}\right\rfloor\) ,真正统计时可分类讨论 \(\max\) 中那个大得解。

\(\text{Part 2}\) : 实际实现

实际中上述 “换根” 并没法很好维护,需重新分类讨论。

以下将要按照最大子树是否在 \(x\) 的子树内,以及割的子树是在 \(x\) 子树内,或是 \(x\) 到根的路径上,或除去 \(x\) 的子树以及 \(x\) 到根的路径上的位置进行讨论:

\(1\):重儿子在 \(x\) 子树内:

\(\text{ }\) \(1.1\):割的子树不在 \(x\) 的重儿子的子树内:

\(\text{ }\) \(\text{ }\) 此时分后 \(x\) 的最大儿子子树大小是 \(mx\)

\(\text{ }\) \(\text{ }\) \(1.1.1\): 割的子树在 \(x\) 的子树内:

\(\text{ }\) \(\text{ }\) \(\text{ }\) \(x\) 所在的分后的树大小为 \(n-t\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 则 \(mx \leq \left\lfloor\frac{n-t}{2}\right\rfloor\) ,即 \(t\leq n-2mx\)

\(\text{ }\) \(\text{ }\) \(1.1.2\): 割的子树在 \(x\) 到根的路径上:

\(\text{ }\) \(\text{ }\) \(\text{ }\) 注意此时 \(x\) 所在的分后的树大小变成 \(t\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 所以 \(mx\leq \left\lfloor\frac{t}{2}\right\rfloor\) ,即 \(t\geq 2mx\)

\(\text{ }\) \(\text{ }\) \(1.1.3\): 割的子树在非 \(x\) 子树内且不在 \(x\) 到根路径上的其他位置:

\(\text{ }\) \(\text{ }\) \(\text{ }\) 此时 \(x\) 所在的分后的树大小是 \(n-t\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 与 \(1.1.1\) 一样 \(t\leq n-2mx\)

\(\text{ }\) \(1.2\): 割的子树在 \(x\) 的重儿子内:

\(\text{ }\) \(\text{ }\) 此时分后 \(x\) 最大儿子子树大小为 \(\max(mx1,mx-t)\)

\(\text{ }\) \(\text{ }\) \(x\) 所在分后的树大小为 \(n-t\)

\(\text{ }\) \(\text{ }\) \(1.2.1\) \(mx-t\leq mx1\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 此时 \(t\geq mx-mx1\) 且 \(mx1 \leq \left\lfloor\frac{n-t}{2}\right\rfloor\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 解得 \(mx-mx1\leq t\leq n-2mx1\)

\(\text{ }\) \(\text{ }\) \(1.2.2\) \(mx-t>mx1\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 此时 \(t\leq mx-mx1-1\) 且 \(mx-t\leq \left\lfloor\frac{n-t}{2}\right\rfloor\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 解得 \(2mx-n\leq t\leq mx-mx1-1\)

\(2.\) 重儿子在 \(x\) 上方

\(\text{ }\) 此时 \(mx=n-size(x)\) , \(size(x)\) 为 \(x\) 的子树大小

\(\text{ }\) \(2.1\) 不在重儿子内割

\(\text{ }\) \(\text{ }\) 此时相当于只在 \(x\) 的子树内割

\(\text{ }\) \(\text{ }\) 割后 \(x\) 所在的树大小为 \(n-t\) ,最大儿子子树大小为 \(mx\)

\(\text{ }\) \(\text{ }\) 所以 \(mx\leq \left\lfloor\frac{n-t}{2}\right\rfloor\) ,即 \(t\leq n-2mx=2size(x)-n\)

\(\text{ }\) \(2.2\) 不在 \(x\) 子树内且不在 \(x\) 到根的路径上割

\(\text{ }\) \(\text{ }\) 此时割后 \(x\) 所在树的大小为 \(n-t\) ,

\(\text{ }\) \(\text{ }\) 最大儿子子树大小为 \(\max(mx-t,mx1)\leq \left\lfloor\frac{n-t}{2}\right\rfloor\)

\(\text{ }\) \(\text{ }\) \(2.2.1\) \(mx-t\leq mx1\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 此时 \(mx-mx1\leq t\) 且 \(mx1\leq \left\lfloor\frac{n-t}{2}\right\rfloor\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 解得 \(n-size(x)-mx1\leq t\leq n-2mx1\)

\(\text{ }\) \(\text{ }\) \(2.2.2\) \(mx-t>mx1\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 此时 \(t\leq mx-mx1-1\) 且 \(mx-t\leq\left\lfloor\frac{n-t}{2}\right\rfloor\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 解得 \(2mx-n\leq t\leq mx-mx1-1\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 也即 \(n-2size(x)\leq t\leq n-size(x)-mx1-1\)

\(\text{ }\) \(2.3\) 在 \(x\) 到根的路径上割

\(\text{ }\) \(\text{ }\) 此时割后 \(x\) 所在的子树大小为 \(t\)

\(\text{ }\) \(\text{ }\) 最大儿子子树大小为 \(\max(t-size(x),mx1)\leq \left\lfloor\frac{t}{2}\right\rfloor\)

\(\text{ }\) \(\text{ }\) \(2.3.1\) \(t-size(x)\leq mx1\)

\(\text{ }\) \(\text{ }\) 此时 \(t\leq mx1+size(x)\) 且 \(mx1\leq \left\lfloor\frac{t}{2}\right\rfloor\)

\(\text{ }\) \(\text{ }\) 解得 \(2mx1\leq t\leq mx1+size(x)\)

\(\text{ }\) \(\text{ }\) \(2.3.2\) \(t-size(x)>mx1\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 此时 \(size(x)+mx1+1\leq t\) 且 \(t-size(x)\leq \left\lfloor\frac{t}{2}\right\rfloor\)

\(\text{ }\) \(\text{ }\) \(\text{ }\) 解得 \(size(x)+mx1+1\leq t\leq 2size(x)\)

一长坨的分类讨论到此结束,考虑如何统计每种情况:

对于查 \(x\) 的子树的信息,可以以子树大小为权值, \(\text{dfs}\) 序为根的编号建一颗主席树。

对于查 \(x\) 到根的信息,可以以子树大小为权值,每次从其父亲更新过来,建成另一棵主席树。

注意 \(x\) 的子树大小不必加进来,到其儿子的版本再加。

这样不在 \(x\) 子树内且不在 \(x\) 到根路径上的信息,可转化为不在 \(x\) 子树内的信息减去 \(x\) 到根的信息,这两颗主席树足以胜任。

时空复杂度都是 \(O(n\log n)\),由于分类讨论众多,常数略大。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10,M=1e7+10;
int T,n,m,x,y,tot,edg,tt,lim,_lim,tmp,res;long long ans;
int to[N<<1],nextn[N<<1],h[N];char ch;
struct tree{int l,r,s;}t[M<<1];
int dfn[N],rev[N],size[N],son[N],mxsz[N],rt[N],rt1[N];
#define add(x,y) to[++edg]=y,nextn[edg]=h[x],h[x]=edg
inline void read(int &x){
	x=0;ch=getchar();
	while(ch<48||ch>57)ch=getchar();
	while(ch>47&&ch<58)x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
}
void write(long long x){if(x>9)write(x/10);putchar(48+x%10);}
void update(int &k,int kk,int l,int r,int pos){
	k=++tot;t[k]=t[kk];++t[k].s;
	if(l^r){
		int mid=(l+r)>>1;
		if(pos<=mid)update(t[k].l,t[kk].l,l,mid,pos);
		else update(t[k].r,t[kk].r,mid+1,r,pos);
	}
}
void inquiry(int k1,int k2,int l,int r,int x,int y){
	if(x<=l&&r<=y)res+=t[k2].s-t[k1].s;
	else {
		int mid=(l+r)>>1;
		if(x<=mid)inquiry(t[k1].l,t[k2].l,l,mid,x,y);
		if(mid<y)inquiry(t[k1].r,t[k2].r,mid+1,r,x,y);
	}
}
void inquiry1(int k,int l,int r,int x,int y){
	if(x<=l&&r<=y)res+=t[k].s;
	else {
		int mid=(l+r)>>1;
		if(x<=mid)inquiry1(t[k].l,l,mid,x,y);
		if(mid<y)inquiry1(t[k].r,mid+1,r,x,y);
	}
}
void dfs(int x,int anc){
	int i,y;rev[dfn[x]=++tt]=x;size[x]=1;
	for(i=h[x];y=to[i],i;i=nextn[i])if(y^anc){
		dfs(y,x);
		size[x]+=size[y];
		if(size[y]>=size[son[x]])mxsz[x]=size[son[x]],son[x]=y;
		else if(size[y]>=mxsz[x])mxsz[x]=size[y];
	}
	if(n-size[x]>=size[son[x]])mxsz[x]=size[son[x]],son[x]=-1;
	else if(n-size[x]>=mxsz[x])mxsz[x]=n-size[x];
}
void dfs_(int x,int anc){
	if(anc>1)update(rt1[x],rt1[anc],1,n,size[anc]);int i,y;
	for(i=h[x];y=to[i],i;i=nextn[i])if(y^anc)dfs_(y,x);
}
void inq(int x){
	res=0;inquiry(rt[0],rt[dfn[x]-1],1,n,lim,_lim);tmp+=res;
	res=0;inquiry(rt[dfn[x]+size[x]-1],rt[n],1,n,lim,_lim);tmp+=res;
	res=0;inquiry1(rt1[x],1,n,lim,_lim);tmp-=res;
}
main(){
	read(T);register int i;
	while(T--){
		read(n);
		for(i=1;i^n;++i)read(x),read(y),add(x,y),add(y,x);
		dfs(1,0);
		for(i=2;i<=n;++i)update(rt[i],rt[i-1],1,n,size[rev[i]]);
		dfs_(1,0);
		for(x=1;x<=n;++x){
			tmp=res=0;
			if(son[x]<0){
				lim=(size[x]<<1)-n;
				if(lim>0)inquiry(rt[dfn[x]],rt[dfn[x]+size[x]-1],1,n,1,lim),tmp=res;
				
				lim=max(n-size[x]-mxsz[x],1);_lim=n-(mxsz[x]<<1);
				if(lim<=_lim)inq(x);
				lim=max(n-(size[x]<<1),1);_lim=n-size[x]-mxsz[x]-1;
				if(lim<=_lim)inq(x);
				
				lim=(mxsz[x]<<1);_lim=mxsz[x]+size[x];res=0;
				if(lim<=_lim)inquiry1(rt1[x],1,n,lim,_lim),tmp+=res;
				lim=mxsz[x]+size[x]+1;_lim=(size[x]<<1);res=0;
				if(lim<=_lim)inquiry1(rt1[x],1,n,lim,_lim),tmp+=res;
				
				if(mxsz[x]<=(size[x]>>1))++tmp;
			}
			else {
				y=son[x];lim=n-(size[y]<<1);
				
				if(lim>0){
					
					res=0;inquiry(rt[dfn[x]],rt[dfn[y]-1],1,n,1,lim);tmp=res;
					res=0;inquiry(rt[dfn[y]+size[y]-1],rt[dfn[x]+size[x]-1],1,n,1,lim);tmp+=res;
					
					res=0;inquiry(rt[0],rt[dfn[x]-1],1,n,1,lim);tmp+=res;
					res=0;inquiry(rt[dfn[x]+size[x]-1],rt[n],1,n,1,lim);tmp+=res;
					res=0;inquiry1(rt1[x],1,n,1,lim);tmp-=res;
				}
				res=0;lim=min(size[y]<<1,n);
				inquiry1(rt1[x],1,n,lim,n);tmp+=res;
				if(size[y]<=(size[x]>>1)&&x^1)++tmp;
				
				lim=max(size[y]-mxsz[x],1);_lim=n-(mxsz[x]<<1);res=0;
				if(lim<=_lim)inquiry(rt[dfn[y]-1],rt[dfn[y]+size[y]-1],1,n,lim,_lim),tmp+=res;
				lim=max((size[y]<<1)-n,1);_lim=size[y]-mxsz[x]-1;res=0;
				if(lim<=_lim)inquiry(rt[dfn[y]-1],rt[dfn[y]+size[y]-1],1,n,lim,_lim),tmp+=res;
				
			}
			
			ans+=1ll*tmp*x;
		}
		write(ans);putchar('\n');
		for(i=1;i<=n;++i)h[i]=size[i]=mxsz[i]=son[i]=rt[i]=rt1[i]=0;
		for(i=1;i<=tot;++i)t[i].l=t[i].r=t[i].s=0;
		tot=edg=ans=tt=0;
	}
}

标签:子树,P5666,重心,题解,mx1,leq,text,mx,size
来源: https://www.cnblogs.com/Y-B-X/p/15363544.html

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

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

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

ICode9版权所有