CodeForces 621C Wet Shark and Flowers

方法可以转化一下,先计算每一个鲨鱼在自己范围内的数能被所给素数整除的个数有几个,从而得到能被整除的概率,设为f1,不能被整除的概率设为f2.

然后计算每相邻两只鲨鱼能获得钱的期望概率,f=w[id1].f1*w[id2].f2+w[id1].f2*w[id2].f1+w[id1].f1*w[id2].f1;

f*2000就是这两只鲨鱼能获得的期望金钱,然后枚举一下所有相邻的鲨鱼,累加即可。

 

#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn=100000+10;
struct X
{
    int tot;//总共的个数
    int t;//能被整除的个数
    double f1;
    double f2;
}w[maxn];
int n,p;

int main()
{
    scanf("%d%d",&n,&p);
    for(int i=0;i<n;i++)
    {
        int li,ri;
        scanf("%d%d",&li,&ri);
        int q1,q2;
        q1=li/p;
        if(q1*p<li) q1++;
        q2=ri/p;
        if(q2*p>ri) q2--;
        if(q2<q1) w[i].t=0;
        else w[i].t=q2-q1+1;
        w[i].tot=ri-li+1;
    }

    for(int i=0;i<n;i++)
    {
        w[i].f1=1.0*w[i].t/w[i].tot;
        w[i].f2=1.0*(w[i].tot-w[i].t)/w[i].tot;

      //  printf("%lf %lf\n",w[i].f1,w[i].f2);
    }

    double ans=0;
    for(int i=0;i<n;i++)
    {
        int id1=i;
        int id2=(i+1)%(n);

        double f=w[id1].f1*w[id2].f2+w[id1].f2*w[id2].f1+w[id1].f1*w[id2].f1;
      //  printf("%lf\n",f);
        ans=ans+2000*f;
    }
    printf("%.5lf\n",ans);
    return 0;
}

 

你可能感兴趣的:(CodeForces 621C Wet Shark and Flowers)