LOJ#2267. 「SDOI2017」龍與地下城【正態分佈與中心極限定理】

題目描述:

link

題目分析:

正態分佈函數:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
YY 較小時用 DP/FFT/求導快速冪,DP的複雜度是 O(YXY)O(Y*XY) 的,考慮上一輪對下一輪的貢獻是一個區間的形式,先打差分標記然後前綴和。求導做快速冪是 O(XXY)O(X*XY) 的。
YY 較大時用正態分佈函數擬合求 [Anμnσ,Bnμnσ]\left[\frac {A-n\mu}{ \sqrt n\sigma},\frac {B-n\mu}{\sqrt n\sigma}\right] 的積分,用自適應辛普森,或者C++自帶的erferf函數
注意方差是σ2\sigma^2

另外還有用去掉頭尾優化FFT、以及模意義下的組合方法,詳見這篇博客

Code:

#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-8, Pi = acos(-1), K = 1/sqrt(2*Pi);
int T,X,Y,A,B;
double f(double x){return K*exp(-x*x/2);}
double F(double L,double R){
	return (R-L)*(f(L)+4*f((L+R)/2)+f(R))/6;
}
double Simpson(double L,double R,int dep){
	double M=(L+R)/2,S=F(L,R),SL=F(L,M),SR=F(M,R);
	if(dep>3&&fabs(S-SL-SR)<eps) return S;
	return Simpson(L,M,dep+1)+Simpson(M,R,dep+1);
}
int main()
{
	for(scanf("%d",&T);T--;){
		scanf("%d%d",&X,&Y);
		double p = 1./X, mu = (X-1)*0.5, sig = (X*X-1)/12.0;
		if(Y<=800){
			static double f[2][805*25];
			int now=0,L=0,R=0; f[now][0]=1;
			for(int i=1;i<=Y;i++,now=!now){
				for(int j=L;j<R+X;j++) f[!now][j]=0;
				while(L<=R&&f[now][L]<eps) ++L;
				while(L<=R&&f[now][R]<eps) --R;
				for(int j=L;j<=R;j++) f[!now][j]+=f[now][j]*p,f[!now][j+X]-=f[now][j]*p;
				R+=X-1;
				for(int j=L+1;j<=R;j++) f[!now][j]+=f[!now][j-1];
			}
			for(int i=L+1;i<=R;i++) f[now][i]+=f[now][i-1];
			for(int i=1;i<=10;i++) scanf("%d%d",&A,&B),printf("%.6f\n",f[now][min(R,B)]-(A<=L?0:f[now][min(R,A-1)]));
		}
		else
			for(int i=1;i<=10;i++){
				scanf("%d%d",&A,&B);
				double l=(A-Y*mu)/(sqrt(Y*sig)),r=(B-Y*mu)/(sqrt(Y*sig));
				printf("%.6f\n",Simpson(l,r,0));
			}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章