1. 程式人生 > 其它 >CF GYM 103102J

CF GYM 103102J

題目

每個點都有 \(\frac{1}{2}\) 的概率有寶藏,現在給出每個點與離它最遠的寶藏的距離 \(d_i\),求在此條件下每個點有寶藏的概率,輸出寶藏編號 (以概率為第一關鍵字,編號為第二關鍵字升序排列)

題解

條件概率題。。設 \(P(A|B)\) 表示在 \(B\) 事件發生的情況下 \(A\) 事件發生的概率

現在知道了每個點與離它最遠寶藏的距離,那麼我們可以發現對於一個根 \(u\) 來說,所有 深度 \(>d_u\) 的一定都不可能有寶藏,且它限制了 深度 \(=d_u\) 的點集中一定至少有一個點有寶藏,假如不考慮其它點的限制,那麼對於 深度 \(<d_u\) 的點,概率都不會受到 \(u\)

的限制 。

但現在有了其它點的限制,該怎麼做?

有一個性質:樹上一個點 \(u\) 到一個點集 \(S\) 中的點最遠距離,一定是由 \(u\)\(S\) 的直徑端點 \(v_1,v_2\) 其中一個構成的。由此我們可以發現每個點的 \(d_i\) 值實際上只表示了它距離 寶藏點集 直徑兩個端點的最大值,那麼直徑的中點一定是 \(d_i\) 值最小的。

先考慮直徑長度為偶數,即只有一箇中點,\(d\) 陣列中只有一個最小值。設這個點為 \(v\) ,將其當根,則它的限制為: 深度 \(=d_v\) 的點集中,至少有兩個 不同 子樹內的點有寶藏;\(< d_v\) 的點集,它們的 \(d\)

值肯定也都表示的是另一棵不同子樹內 深度 \(=d_v\) 的點集至少有一個寶藏,這個限制被 \(v\) 的限制完全包含,所以不需要考慮;\(>d_v\) 的點集,情況同上。

這麼一分類,可以發現 深度 \(<d_v\) 的點沒有受到任何限制,概率仍然是 \(\frac{1}{2}\)\(>d_v\) 的點概率也一定是 \(0\),現在只需要考慮 \(=d_v\) 的點之間概率的大小關係。

可以發現,對於每個點 \(u\) ,設事件 \(A\) 為 “ \(u\) 點有寶藏,且除了該點所屬子樹之外,還有至少一棵另外子樹 深度\(=d_v\) 的點處有寶藏”,事件 \(B\)

為 “至少有兩個不同子樹內的 深度\(=d_v\) 的點處有寶藏”,則 \(P(u)=\frac{P(A)}{P(B)}\) ,由於所有的點 \(P(B)\) 是一樣的,所以只需要考慮 \(P(A)\) 的大小。

\(P(A)\) 可以拆成兩部分來看 “ \(u\) 點有寶藏” 的概率仍然是每個點都一樣,即 \(\frac{1}{2}\) 。那麼概率的區別就在於 “還有至少一棵另外子樹 深度\(=d_v\) 的點處有寶藏” 設 深度\(=d_v\) 的點的總個數為 \(sum\),點 \(u\) 所屬子樹中 有 \(siz_u\) 個點 深度\(=d_u\) ,概率即為 \(1-(1-\frac{1}{2})^{sum-siz_u}\) ,由此可得 \(siz_u\) 越大,出現寶藏的概率越小。

直徑長度為奇數,即有兩個中點,與上面類似考慮即可。

PS:這道題由 點到點集最遠距離 轉化到了直徑上的問題。。然後分析一下,奇奇怪怪的限制少了很多。。

const int N=3e5+5;
int n,x,y,a[N],id,minn=1e9,deep[N],flag,pre;
vi v[N],g[N],f[N],ans,cy;
vector<pii>w;
void dfs(int u,int fa,int id){
	deep[u]=deep[fa]+1;
	if(deep[u]<minn)ans.pb(u);
	else if(deep[u]==minn)f[id].pb(u);
	else cy.pb(u);
	for(auto i:v[u]){
		if(i==fa)continue;
		dfs(i,u,id);
	}
}
int main(){
	#ifdef newbiewzs
	#else
	#endif
	n=read();
	for(int i=1;i<n;i++){
		x=read();y=read();
		v[x].pb(y);
		v[y].pb(x);
	}
	for(int i=1;i<=n;i++)a[i]=read();
	for(int i=1;i<=n;i++){
		if(minn>a[i]){
			minn=a[i];id=i;
		}
	}
	for(int i=1;i<=n;i++){
		if(minn==a[i] && id!=i)flag=1,pre=i;
	}
	if(flag){
		dfs(pre,id,pre);
		for(auto ta:f[pre]){
			w.pb(mp(f[pre].size(),ta));
		}
		memset(deep,0,sizeof(deep));
		dfs(id,pre,id);
		for(auto ta:f[id]){
			w.pb(mp(f[id].size(),ta));
		}
	}
	else{
		for(auto tmp:v[id]){
			dfs(tmp,id,tmp);
			for(auto ta:f[tmp]){
				w.pb(mp(f[tmp].size(),ta));
			}
		}
		if(minn==0)w.pb(mp(0,id));
		else ans.pb(id);
	}
	
	
	sort(w.begin(),w.end());
	sort(ans.begin(),ans.end());
	sort(cy.begin(),cy.end());
	for(auto ta:w){
		cout<<ta.se<<" ";
	}
	for(auto tb:ans){
		cout<<tb<<" ";
	}
	for(auto tc:cy){
		cout<<tc<<" ";
	}
	return 0;
}