牛客训练赛n的约数题解

题外话

艹他奶奶的,我都快写完了忘记保存了!

正文

很好的题目,让我的大脑旋转

容易想到将x1-xn设为在1-n号点爆炸的概率,mapp[i][j]设为从i到j不爆炸转移的概率。

错误方法

代码:

for(int i=1;i<=m;i++){
		mapp[u[i]][v[i]]=(1-p/q)/du[v[i]];
		mapp[v[i]][u[i]]=(1-p/q)/du[u[i]];
	}
	for(int i=1;i<=n;i++){
		mapp[i][i]=1;
	}
	mapp[1][n+1]=(double)p/q;
此次省略高斯消元模板

好,直接交!

好,WA0分!

好,不做了!水犇犇去啦!

那么,为啥不对呢?

非常恶心的细节处理

仔细想一想,你用爆炸的概率 * 不爆炸转移的概率是啥?啥也不是好吧!

正常来讲,应该用不爆炸的概率 * 转移成功的概率。

这时,思考一下不爆炸的概率和爆炸的概率的关系。

显然,不爆炸概率=1-爆炸概率

AC code

#include<bits/stdc++.h>
using namespace std;
double mapp[310][310],p,q;
int u[44855],v[44855],du[44855];
int n,m;
int main(){
	cin>>n>>m>>p>>q;
	for(int i=1;i<=m;i++){
		cin>>u[i]>>v[i];
		du[u[i]]++;
		du[v[i]]++;
	}
	for(int i=1;i<=m;i++){
		mapp[u[i]][v[i]]=((double)p/q-1)/du[v[i]];
		mapp[v[i]][u[i]]=((double)p/q-1)/du[u[i]];
	}
	for(int i=1;i<=n;i++){
		mapp[i][i]=1;
	}
	mapp[1][n+1]=(double)p/q;
	int r;
	for(int i=1;i<=n;i++){
		r=i;
		for(int j=i;j<=n;j++){
			if(fabs(mapp[r][i])<fabs(mapp[j][i])){
				r=j;
			}
		}
		swap(mapp[i],mapp[r]);
		double t=mapp[i][i];
		for(int j=i+1;j<=n;j++){
			t=mapp[j][i]/mapp[i][i];
			for(int k=i;k<=n+1;k++){
				mapp[j][k]-=mapp[i][k]*t;
			}
		}
	}
	for(int i=n;i>=1;i--){
		for(int j=i+1;j<=n;j++){
			mapp[i][n+1]-=mapp[i][j]*mapp[j][n+1];
		}
		mapp[i][n+1]/=mapp[i][i];
	}
	for(int i=1;i<=n;i++){
		printf("%.9lf\n",(mapp[i][n+1]));
	}
}
posted @ 2024-04-19 23:08  LEWISAK  阅读(34)  评论(0)    收藏  举报