题解-概率计算器

Problem

求给定式子的期望:题面

Solution

由于式子是由\(\max ,\min\)组成的,而这东西是基于比较大小的,所以我们需要想想在基于比较的情况下方便实现的东西

\(f(x)\)表示式子小于等于\(x\)的概率,\(g(x)\)表示式子大于等于\(x\)的概率


则对于单个变量,易证有:

\(f(x)=x\\g(x)=1-f(x)\)

对于式子\(\max(x_1,x_2)\)

\[f(x)=f_1(x)\cdot f_2(x) \]

\[g(x)=1-f_1(x)\cdot f_2(x) \]

对于式子\(\min(x_1,x_2)\)

\[g(x)=g_1(x)\cdot g_2(x) \]

\[f(x)=1-g_1(x)\cdot g_2(x) \]


接下来考虑如何统计答案

众所周知,答案可以表达为

\[\int_0^1p(ans=x)\cdot x\cdot dx \]

由于\(f(x)\)表示的是式子小于等于\(x\)的概率

\(f(x)=p(ans\leq x)\),则有\(f'(x)=p(ans=x)\)

即最终答案为

\[\int_0^1f'(x)\cdot x\cdot dx \]

\(f(x)\)可以由递归求解

至于原式的话,只要简单求导积分即可


注意:如果在oj上下了数据,并且在第六位小数处出现1的误差,是因为oj上下载数据的链接有问题?提交即可AC

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rg register

template <typename _Tp> inline _Tp read(_Tp&x){
	char c11=getchar(),ob=0;x=0;
	while(c11^'-'&&!isdigit(c11))c11=getchar();if(c11=='-')ob=1,c11=getchar();
	while(isdigit(c11))x=x*10+c11-'0',c11=getchar();if(ob)x=-x;return x;
}

const int N=100;
int l[N],r[N],m[N];
int ps[10101],st[N];
char s[10101];
int n,len;

struct poly{
	ll a[N];int d;
	inline poly(){memset(a,0,sizeof(a)),d=0;}
	friend inline poly operator * (poly A,poly B){
		poly res;res.d=A.d+B.d-1;
		for(rg int i=0;i<A.d;++i)
		for(rg int j=0;j<B.d;++j)
			res.a[i+j]+=A.a[i]*B.a[j];
		return res;
	}
	friend inline poly operator - (poly A,poly B){
		poly res;res.d=max(A.d,B.d);
		for(rg int i=0;i<res.d;++i)
			res.a[i]=A.a[i]-B.a[i];
		return res;
	}
	inline void deri(){
		for(rg int i=0;i<d-1;++i)
			a[i]=a[i+1]*(i+1);
		a[--d]=0;
	}
}ans,vec;

poly calc(int opt,int L,int R){
	if(s[L+1]=='x'){
		poly res;res.d=2;
		if(!opt)res.a[1]=1;
		else res.a[1]=-1,res.a[0]=1;
		return res;
	}
	for(int i=L+1;i<=R;++i)if(ps[i]){
		int id=ps[i];
		if(!opt)
			if(s[i-1]=='x')return calc(opt,l[id],m[id])*calc(opt,m[id]+1,r[id]);
			else return vec-(calc(opt^1,l[id],m[id])*calc(opt^1,m[id]+1,r[id]));
		else
			if(s[i-1]=='n')return calc(opt,l[id],m[id])*calc(opt,m[id]+1,r[id]);
			else return vec-(calc(opt^1,l[id],m[id])*calc(opt^1,m[id]+1,r[id]));
	}
}

void init();
int main(){
	vec.d=2;vec.a[0]=1;
	while(~scanf("%s",s)){
		init();
		ans=calc(0,-1,len-1);
		ans.deri();
		for(rg int i=ans.d;i;--i)
			ans.a[i]=ans.a[i-1];
		ans.a[0]=0;++ans.d;
		double res=0;
		for(rg int i=ans.d;i;--i)
			res+=1.0*(ans.a[i-1]%i)/i;
		while(res<=0)++res;while(res>=1)--res;
		printf("%.6lf\n",res);
	}return 0;
}

void init(){
	scanf("%s",s);getchar();
	cin.getline(s,10000);
	len=strlen(s);
	memset(ps,0,sizeof(ps));
	int idc=0,tp=0;
	for(int i=0;i<len;++i){
		if(s[i]=='(')ps[l[st[++tp]=++idc]=i]=idc;
		else if(s[i]==',')m[st[tp]]=i;
		else if(s[i]==')')r[st[tp--]]=i;
	}
}
posted @ 2018-09-19 17:37  oier_hzy  阅读(421)  评论(0编辑  收藏  举报