Wet Shark and Flowers
Limit 2s,256M
There are n sharks who grow flowers for Wet Shark. They are all sitting around the table, such that sharks i and i + 1 are neighbours for all i from 1 to n - 1. Sharks n and 1 are neighbours too.
Each shark will grow some number of flowers si. For i-th shark value si is random integer equiprobably chosen in range from li to ri. Wet Shark has it's favourite prime number p, and he really likes it! If for any pair of neighbouring sharks i and j the product si·sj is divisible by p, then Wet Shark becomes happy and gives 1000 dollars to each of these sharks.
At the end of the day sharks sum all the money Wet Shark granted to them. Find the expectation of this value.
Input
The first line of the input contains two space-separated integers n and p (3 ≤ n ≤ 100 000, 2 ≤ p ≤ 10^9) — the number of sharks and Wet Shark's favourite prime number. It is guaranteed that p is prime.
The i-th of the following n lines contains information about i-th shark — two space-separated integers li and ri (1 ≤ li ≤ ri ≤ 109), the range of flowers shark i can produce. Remember that si is chosen equiprobably among all integers from li to ri, inclusive.
Output
Print a single real number — the expected number of dollars that the sharks receive in total. You answer will be considered correct if its absolute or relative error does not exceed 10 - 6.
Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .
Example
Input
3 2
1 2
420 421
420420 420421
Output
4500.0
题意
n个鲨鱼围着一个圈种花,每个鲨鱼对应一个闭区间[l,r],鲨鱼所种的花的价值是区间里的任意整数,鲨鱼wet喜欢一个质数p,如果相邻鲨鱼的花的价值的积整除p,那么鲨鱼会给这两只鲨鱼一人1000元,问所有鲨鱼所得钱之和的数学期望。
题解
两数之积整除质数p,只要两数中有一个数整除p就可以了,另一个数随意,然后容斥原理一下就好了
1.区间[l,r]内的质数p倍数的个数可以用n=floor(r*1.0/p)-ceil(l*1.0/p)+1计算。
2.注意计算过程中会爆int
3.输出double类型不要用cout,容易挂精度,应该printf(“%.12f\n”,ans)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
long long seg[maxn+5];
long long num[maxn+5];
double math_exp[maxn+5];
int main(void)
{
#ifdef ex
freopen ("in.txt","r",stdin);
#endif
int n,p;
scanf("%d%d",&n,&p);
int l,r;
for (int i=1;i<=n;++i)
{
scanf("%d%d",&l,&r);
seg[i]=r-l+1;
num[i]=floor(r*1.0/p)-ceil(l*1.0/p)+1;
}
for (int i=1;i<=n-1;++i)
{
math_exp[i]=(num[i]*seg[i+1]+num[i+1]*seg[i]-num[i]*num[i+1])*1.0/(seg[i]*seg[i+1]);
}
math_exp[n]=(num[n]*seg[1]+num[1]*seg[n]-num[n]*num[1])*1.0/(seg[1]*seg[n]);
double ans=0.0;
for (int i=1;i<=n;++i)
{
ans+=math_exp[i]*2000;
}
printf("%.12f\n",ans);
}