1. 程式人生 > >【HDU 6410】序列期望 百度之星複賽B (數學期望)

【HDU 6410】序列期望 百度之星複賽B (數學期望)

題目大意

有n個隨機變數x1,x2,…,xn。給定區間[l1,r1],…,[ln,rn],變數xi的值會等概率成為區間[li,ri]中的任意一個整數

顯然這n個隨機變數的值會有一共∏ni=1(ri−li+1) 種情況,且每種情況出現的概率為 i=1nrili+1

對於某種情況,令h=max{x1,x2,…,xn},定義這種情況的權值為:i=1n(hxi+1).

想知道權值的期望是多少?請將答案對 1e9+7 取模後輸出。

解題思路

由於數字值域的範圍比較小,所以考慮列舉最大值 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; }