【HDU 6410】序列期望 百度之星复赛B (数学期望)

题目大意

有n个随机变量x1,x2,…,xn。给定区间[l1,r1],…,[ln,rn],变量xi的值会等概率成为区间[li,ri]中的任意一个整数

显然这n个随机变量的值会有一共∏ni=1(ri−li+1) 种情况,且每种情况出现的概率为 ni=1rili+1 ∏ i = 1 n r i − l i + 1

对于某种情况,令h=max{x1,x2,…,xn},定义这种情况的权值为: ni=1(hxi+1) ∏ i = 1 n ( h − x i + 1 ) .

想知道权值的期望是多少?请将答案对 1e9+7 取模后输出。

链接:http://acm.hdu.edu.cn/showproblem.php?pid=6410


解题思路

由于数字值域的范围比较小,所以考虑枚举最大值 h,对于每一个枚举出的最大值,统计出该最大值下的情况的答案,既各个区间保证 h 为最大值的可取的数字之和的乘积。


代码

#include <bits/stdc++.h>
using namespace std;

const int maxn=233, moder=int(1e9)+7;
inline int mul(int a,int b) {return 1ll*a*b%moder;}
inline int add(int a,int b) {return (a+b<moder)?(a+b):(a+b-moder);}
inline int les(int a,int b) {return (a<b)?(a-b+moder):(a-b);}

int n;
int l[maxn], r[maxn];

int fpow(int a,int k) {
    int res=1;
    for(;k;k>>=1,a=mul(a,a)) if(k&1) res=mul(res,a);
    return res;
}

void work() {
    scanf("%d",&n);
    register int i,j;

    int pro=1, maxx=0;
    for(i=1;i<=n;++i) {
        scanf("%d%d",&l[i],&r[i]);
        pro=mul(pro,(r[i]-l[i]+1));
        maxx=max(maxx,r[i]);
    }

    int ret=0;
    for(i=1;i<=maxx;++i) {
        int pre=1, cur=1;
        for(j=1;j<=n;++j) {
            int x=l[j], y=min(r[j],i);
            int a=i-x+1, b=i-y+1;
            if(a<b) cur=0;
            else cur=mul(cur,(b+a)*(a-b+1)/2%moder);

            x=l[j], y=min(r[j],i-1);
            a=i-x+1, b=i-y+1;
            if(a<b) pre=0;
            else pre=mul(pre,(b+a)*(a-b+1)/2%moder);
        }
        ret=add(ret,les(cur,pre));
    }

    ret=mul(ret,fpow(pro,moder-2));
    cout<<ret<<endl;

    return;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
#endif
    int T;
    for(scanf("%d",&T);T;T--)
        work();

    return 0;
}
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页