ABC.173.F - Intervals on Tree

ABC.173.F - Intervals on Tree

传送门

题意:给定nn个结点n1n-1条边的树,求结点的所有子集([l,r])(区间[l,r])的连通块的和。

思路:考虑最开始为nn个孤立点的所有子集的连通块的和,再减去每条边对于连通块的贡献。

显然每个点就是一个连通块。

考虑包含11的子集(区间): l1,r1l\leq1,r\geq1ll有1种选择,rrn1+1n-1+1种选择。

1×(n1+1)=n1\times(n-1+1)=n种选择。

包含22子集(区间):l2,r2l\leq2,r\geq2ll22种选择,rrn2+1n-2+1种选择。

2×(n2+1)=2×(n1)2\times(n-2+1)=2\times(n-1)

依次类推:

可得总连通块数:

i=1ni×(ni+1)=(n+1)×i=1nii=1ni2=(n+1)×n(n+1)2n(n+1)(n+2)6=n(n+1)(3n+3(n+2))6=n(n+1)(2n+1)6\sum\limits_{i=1}^ni\times(n-i+1)\\=(n+1)\times\sum\limits_{i=1}^ni-\sum\limits_{i=1}^ni^2\\=(n+1)\times \dfrac{n(n+1)}{2}-\dfrac{n(n+1)(n+2)}{6}\\=\dfrac{n(n+1)(3n+3-(n+2))}{6}\\=\dfrac{n(n+1)(2n+1)}{6}

显然对于边(u,v)(u,v),(假设u<vu<v,因为区间lrl\leq r),显然包含边(u,v)(u,v)的子集(区间)。

lu,rvl\leq u,r\geq v,一共u×(nv+1)u\times(n-v+1)个子集,每个子集因为u,vu,v的相连会把u,vu,v两个连通块减为11个。所以答案要减去u×(nv+1)u\times(n-v+1)

所以一边读入一边减去贡献即可。

时间复杂度:O(n)O(n)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first 
#define se second
int main(){
	int n;
	scanf("%d",&n);
	ll ans=1LL*n*(n+1)*(n+2)/6;
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		if(u>v) swap(u,v);
		ans-=1LL*u*(n-v+1); 
	}
	printf("%lld\n",ans); 
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章