标签:
题目链接:点击打开链接
题意:有n个人围坐成一圈,每个人可以从a[i].l 到 a[i].r里选一个数,如果相邻两个数的乘积能整除p,那么就奖励他们一人1000,求所得钱的总和的期望。
思路:既然求期望, 先求概率。 显然是要求每组相邻两个人的值乘积能否被p整除, 可以很容易知道在区间里有多少个数不能被p整除, 正难则反, 就能算出相邻两个有多少种组合不能被p整除, 那么也就很容易算出每组可以被p整除的概率, 乘上2000就是每组的期望, 期望加和就是总的期望。
细节参见代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) using namespace std; typedef long long ll; const double PI = acos(-1.0); const double eps = 1e-6; const int mod = 1000000000 + 7; const int INF = 1000000000; const int maxn = 100000 + 10; int T,n,m,p; struct node { int l, r, num; double p; }a[maxn]; int main() { scanf("%d%d",&n,&p); for(int i=0;i<n;i++) { scanf("%d%d",&a[i].l,&a[i].r); a[i].num = a[i].r/p - (a[i].l - 1)/p; } double ans = 0; for(int i=0;i<n;i++) { int j = (i + 1) % n; double la = a[i].l, ra = a[i].r, lb = a[j].l, rb = a[j].r; double c1 = a[i].num, c2 = a[j].num; a[i].p = 1.0 - (double)(ra - la + 1 - c1)/(double)(ra - la + 1) * (double)(rb - lb + 1 - c2)/(double)(rb - lb + 1); ans += a[i].p; } printf("%.8f\n",ans*2000); return 0; }
Codeforces Round #341 (Div. 2) C. Wet Shark and Flowers(简单容斥)
标签:
原文地址:http://blog.csdn.net/weizhuwyzc000/article/details/50617966