2018“百度之星”程式設計大賽
序列期望
Accepts: 531
Submissions: 1078
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
Problem Description
"看似隨機,實則早已註定"——光羽
度度熊有nnn個隨機變數x1,x2,...,xnx_1,x_2,...,x_nx1,x2,...,xn。給定區間[l1,r1],...,[ln,rn][l_1, r_1],...,[l_n, r_n][l1,r1],...,[ln,rn],變數xix_ixi的值會等概率
顯然這nnn個隨機變數的值會有一共∏i=1n(ri−li+1)\prod_{i=1}^{n} (r_i - l_i + 1) ∏i=1n(ri−li+1) 種情況,且每種情況出現的概率為∏i=1n1ri−li+1\prod_{i=1}^{n} \frac{1}{r_i - l_i + 1}∏i=1nri−li+11 。
對於某種情況,令h=max{x1,x2,...,xn}h= \max{ x_1,x_2,...,x_n}h=max{x1,x2,...,xn},定義這種情況的權值
度度熊想知道權值的期望是多少?請將答案對109+710^9 + 7109+7取模後輸出。
PS:不清楚期望是啥?為什麼不問問神奇的百度呢?
Input
第一行一個數,表示資料組數TTT。
每組資料第一行一個整數nnn;接下來nnn行,每行兩個數,表示lil_ili和rir_iri。
資料組數T=100,滿足:
- 1≤n≤1001 \le n \le 1001≤n≤100
- 1≤li≤ri≤1041 \le l_i \le r_i \le 10^41≤li≤ri≤104
其中70%的資料滿足ri≤100r_i \le 100ri≤100。
Output
每組資料輸出一行,每行僅包含一個數,表示期望。
假設答案為pq\frac{p}{q}qp,請輸出p×q−1 mod 109+7p \times q^{-1} ~mod~10^9+7p×q−1 mod 109+7,此處q−1q^{-1}q−1為qqq的逆元。
Sample Input
Copy
2
3
2 5
2 4
2 5
3
1 1
2 3
1 1
Sample Output
Copy
875000012
500000010
Hint
第二組資料的解釋:序列只有兩種情況(1,2,1)和(1,3,1),權值分別為2*1*2=4和3*1*3=9,答案為(4+9)/2,在模域下為500000010。
暴力每個最大值,然後分別求貢獻即可。
#include<vector>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define mod 1000000007
int n;
ll ans,l[105],r[105];
ll q(ll x,ll y)
{
ll res=1;
while(y)
{
if(y%2)
res=res*x%mod;
x=x*x%mod;
y/=2;
}
return res;
}
ll work(ll l,ll r)
{
if(r<l)
return 0;
else
return (ll)(l+r)*(r-l+1)/2;
}
int main(void)
{
int T;
scanf("%d",&T);
while(T--)
{
ll x=0,y=1,ls=0,rs=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&l[i],&r[i]);
y=y*(r[i]-l[i]+1)%mod;
ls=max(ls,l[i]);rs=max(rs,r[i]);
}
for(int i=ls;i<=rs;i++)
{
ll sm1=1,sm2=1;
for(int j=1;j<=n;j++)
{
ll lll=l[j],rrr=min(r[j],(ll)i);
sm1=sm1*work(i+1-rrr,i+1-lll)%mod;
}
for(int j=1;j<=n;j++)
{
ll lll=l[j],rrr=min(r[j],(ll)(i-1));
sm2=sm2*work(i+1-rrr,i+1-lll)%mod;
}
x=(x+(sm1-sm2+mod)%mod)%mod;
}
printf("%lld\n",x*q(y,mod-2)%mod);
}
}