【bzoj2134】单选错位 期望

题目描述

输入

n很大,为了避免读入耗时太多,输入文件只有5个整数参数n, A, B, C, a1,由上交的程序产生数列a。下面给出pascal/C/C++的读入语句和产生序列的语句(默认从标准输入读入): // for pascal readln(n,A,B,C,q[1]); for i:=2 to n do q[i] := (int64(q[i-1]) * A + B) mod 100000001; for i:=1 to n do q[i] := q[i] mod C + 1; // for C/C++ scanf("%d%d%d%d%d",&n,&A,&B,&C,a+1); for (int i=2;i<=n;i++) a[i] = ((long long)a[i-1] * A + B) % 100000001; for (int i=1;i<=n;i++) a[i] = a[i] % C + 1; 选手可以通过以上的程序语句得到n和数列a(a的元素类型是32位整数),n和a的含义见题目描述。

输出

输出一个实数,表示gx期望做对的题目个数,保留三位小数。

样例输入

3 2 0 4 1

样例输出

1.167


题解

期望

由于期望在任何时候都是可加的,所以我们只需要求出第i个答案正确的概率,把它们加起来即可。

而第i个答案正确的概率为$\frac{min(a[i],a[i\mod n+1])}{a[i]·a[i\mod n+1]}=\frac 1{max(a[i],a[i\mod n+1])}$,把这些数加起来即为答案。

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
ll a[10000010];
int main()
{
    int n , A , B , C , i;
    double ans = 0;
    scanf("%d%d%d%d%lld" , &n , &A , &B , &C , &a[1]);
    for(i = 2 ; i <= n ; i ++ ) a[i] = (a[i - 1] * A + B) % 100000001;
    for(i = 1 ; i <= n ; i ++ ) a[i] = a[i] % C + 1;
    for(i = 1 ; i <= n ; i ++ ) ans += 1.0 / max(a[i] , a[i % n + 1]);
    printf("%.3lf\n" , ans);
    return 0;
}

 

 

posted @ 2017-08-18 19:44  GXZlegend  阅读(338)  评论(0编辑  收藏  举报