【概率与期望】[CodeForces - 621C]Wet Shark and Flowers

来源:互联网 发布:java 视频 最好 编辑:程序博客网 时间:2024/06/05 06:45

题目大意

有n个鲨鱼围成一圈,每个鲨鱼有一个写着数字的花,第i个鲨鱼的数字在[li,ri]区间等概率选取,如果有相邻的两个鲨鱼数字的乘积是p的倍数,那Wet Shark就会给他们每人1000元。

分析

样本空间的大小为

S=i=1n(rili+1)

每种情况是概率出现的,只需要将所有情况的Wet Shark需要付的钱加起来除以S即可。
然而,显然直接不能这样做,我们考虑优化。
令第i只鲨鱼的取值中有npi个数字被p整除。
npi=ripli1p

考虑第i只和i+1只鲨鱼,如果第i只鲨鱼的数字整除p的,那无论第i+1只鲨鱼取什么数字,积都可以被整除。
如果第i只鲨鱼的数字不能被p整除,那么只有当第i+1只鲨鱼取质数时积才能被p整除。
也就是这两只鲨鱼对答案的贡献
Gi=2000(npi(ri+1li+1+1)+(rili+1npi)npi+1)nj=1ji,i+1(rjlj+1)S=2000(npi(ri+1li+1+1)+(rili+1npi)npi+1)nj=1ji,i+1(rjlj+1)nj=1(rjlj+1)=2000(npi(ri+1li+1+1)+(rili+1npi)npi+1)(rili+1)(ri+1li+1+1)

根据这个公式算出答案即可。
注意:1和n也是相邻的。

代码

#include<cstdio>#include<algorithm>using namespace std;#define MAXN 100000int n,p,l[MAXN+10],r[MAXN+10],np[MAXN+10];double ans;void Read(int &x){    char c;    while(c=getchar(),c!=EOF)        if(c>='0'&&c<='9'){            x=c-'0';            while(c=getchar(),c>='0'&&c<='9')                x=x*10+c-'0';            ungetc(c,stdin);            return;        }}void read(){    Read(n),Read(p);    for(int i=1;i<=n;i++){        Read(l[i]),Read(r[i]);        np[i]=r[i]/p-(l[i]-1)/p;    }}void solve(){    int i;    for(i=1;i<=n;i++)        ans+=(1.0*np[i]*(r[i%n+1]-l[i%n+1]+1)+1.0*(r[i]-l[i]+1-np[i])*np[i%n+1])/(r[i]-l[i]+1)*2000/(r[i%n+1]-l[i%n+1]+1);}   int main(){    read();    solve();    printf("%.7lf",ans);}
0 0
原创粉丝点击