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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章