题目链接https://codeforces.com/problemset/problem/621/C
time limit per test 2 seconds
memory limit per test 256 megabytes
emmm,题目大意:给你n个区间si,一个质数p,每当你找到两个数x,y分别属于si和si+1其x*y为p的倍数时,会奖励2000元。问你平均能得到多少元。
emmm,这个平均有点毒,它的总数是按照组合的总数来计算的,也就是说他的总方案为每个区间长度的乘积。则最大总数为109 * 109 *100000。直接原地爆炸。。。所以不能直接暴力。
那么我们可以边算边除,就直接将它转化为概率问题,每个区间长度为len[i],其包含p的倍数的个数为num[i],那么我们所能有的概率为num[i]/len[i],但如果要算不能获得的概率的话,我们必须逆向求解:1-num[i]/len[i]。那么接下来就好办了,每对可能的概率 * 2000相加就完事了。
以下是详细代码:
#include <cstdio>
#define ll long long
const int mac=1e5+7;
int c[mac],nb[mac],l[mac],r[mac];
double pp[mac];
int main()
{
int n,p;
scanf ("%d%d",&n,&p);
for (int i=1; i<=n; i++){
scanf ("%d%d",&l[i],&r[i]);
nb[i]=r[i]/p-(l[i]-1)/p;
c[i]=r[i]-l[i]+1;
pp[i]=1.0-(1.0*nb[i]/c[i]*1.0);
}
pp[n+1]=pp[1];
double ans=0;
for (int i=1; i<=n; i++){
ans+=(1.0-pp[i]*pp[i+1])*2000;
}
printf ("%lf",ans);
return 0;
}