洛谷 P4581 - [BJOI2014]想法(随机化)

奇怪的随机化题,知道题解不长但是还是写一写,以免我忘了这个 trick。

考虑随机给每道题目一个 \([0,V]\) 的权值,然后求出每个点能够到达的点权值的最小值,多次随机取平均值,根据概率论,假设点 \(x\) 的答案为 \(ans_x\),那么这个权值的期望值应当为 \(\dfrac{V}{ans_x+1}\)

根据我们求得的平均权值得到 \(ans\) 即可。

const int MAXN=1e6;
const int V=1e9;
mt19937 rng(time(0));
int n,m,mn[MAXN+5],x[MAXN+5],y[MAXN+5],c;double res[MAXN+5];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=m+1;i<=n;i++)scanf("%d%d",&x[i],&y[i]);
	while(clock()<1.9*CLOCKS_PER_SEC){
		for(int i=1;i<=m;i++)mn[i]=rng()%V+1;
//		for(int i=1;i<=m;i++)printf("%d%c",mn[i]," \n"[i==m]);
		for(int i=m+1;i<=n;i++)mn[i]=min(mn[x[i]],mn[y[i]]);
		for(int i=m+1;i<=n;i++)res[i]+=mn[i];
		c++;
	}
	for(int i=m+1;i<=n;i++)printf("%d\n",(int)round(V/(res[i]/c)-1));
	return 0;
}
posted @ 2022-12-22 12:10  tzc_wk  阅读(50)  评论(0)    收藏  举报