概率计算器

版权声明:写得不好,转载请通知一声,还请注明出处,感激不尽 https://blog.csdn.net/As_A_Kid/article/details/82775789

Problem

████[数据删除]

Solution

这道题研究的是连续型变量,那么为了描述它在各个数值的概率,我们可以用概率密度函数来描述。那啥是概率密度函数啊?

看度娘给我们的解释:
duniang

容易知道 P ( x A ) = 0 A P ( x ) P(x\leq A)=\int_0^AP(x) ,那 P ( x A ) P(x\geq A) 怎么办?看看度娘给的第二条性质,那么就有 P ( x A ) = 1 0 A P ( x ) P(x\geq A)=1-\int_0^AP(x)

那我们来考虑第一个操作对的概率的影响,应该就是
h ( x ) = f ( x ) ( 1 0 x g ( x ) d x ) + g ( x ) ( 1 0 x f ( x ) d x ) h(x)=f(x)(1-\int_0^xg(x)dx)+g(x)(1-\int_0^xf(x)dx)

同样的我们考虑第二个:
h ( x ) = f ( x ) 0 x g ( x ) d x + g ( x ) 0 x f ( x ) d x h(x)=f(x)\int_0^xg(x)dx+g(x)\int_0^xf(x)dx

那么我们维护概率密度函数即可。不知道为什么积分后的函数各项系数还是整数,反正用ll存我们就可以在中间计算时避免精度误差了。

由期望的计算式就有 E = P ( x ) x E=\sum P(x)x ,所以 a n s = 0 1 x f ( x ) d x ans=\int_0^1xf(x)dx

注意精度问题。由于double在变量整数部分较大的时候小数部分精度损失严重,我们不妨直接取其小数部分。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define rg register
using namespace std;
typedef long long ll;
const int maxn=101;
template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
template <typename Tp> inline void read(Tp &x)
{
	x=0;int f=0;char ch=getchar();
	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
	if(ch=='-') f=1,ch=getchar();
	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	if(f) x=-x;
}
struct Poly{
	int deg;
	ll a[maxn];
	Poly(){memset(a,0,sizeof(a));deg=0;}
	Poly operator + (const Poly &b)const
	{
		Poly res;res.deg=max(deg,b.deg);
		for(rg int i=0;i<res.deg;i++) res.a[i]=a[i]+b.a[i];
		return res;
	}
	Poly operator - (const Poly &b)const
	{
		Poly res;res.deg=max(deg,b.deg);
		for(rg int i=0;i<res.deg;i++) res.a[i]=a[i]-b.a[i];
		return res;
	}
	Poly operator * (const Poly &b)const
	{
		Poly res;res.deg=deg+b.deg-1;
		for(rg int i=0;i<deg;i++)
		  for(int j=0;j<b.deg;j++)
		    res.a[i+j]+=a[i]*b.a[j];
		return res;
	}
	Poly inte()
	{
		Poly res;res.deg=deg+1;
		for(rg int i=deg;i;i--) res.a[i]=a[i-1]/i;
		return res;
	}
}a,b,fa,fb,st,tmp,sk[100];
int tp,tk,stk[100];
long double ans;
char s[10010];
int main()
{
	#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif
	st.a[0]=1ll;tmp.a[1]=1ll;
	st.deg=1;tmp.deg=2;
	while(~scanf("%s",s))
	{
		cin.getline(s,10000);
		ans=0.0;tp=tk=0;
		for(rg int i=0;s[i];i++)
		{
			if(s[i]=='m') stk[++tp]=(s[i+1]=='a'?1:0);
			else if(s[i]=='x'&&s[i+1]=='_') sk[++tk]=st;
			else if(s[i]==')')
			{
				a=sk[tk];b=sk[tk-1];tp--;tk--;
				fa=a.inte();fb=b.inte();
				if(stk[tp+1])
				{
					sk[tk]=a*fb+b*fa;
				}
				else
				{
					fa=st-fa;fb=st-fb;
					sk[tk]=a*fb+b*fa;
				}
			}
		}
		sk[1]=sk[1]*tmp;
		for(rg int i=sk[1].deg;i;i--)
		{
			ans+=1.0*(sk[1].a[i-1]%i)/i;
			if(ans>=1.0) ans-=1.0;
			if(ans<0.0) ans+=1.0;
		}
		printf("%.6Lf\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/As_A_Kid/article/details/82775789