2018“百度之星”程序设计大赛 - 复赛-1002-序列期望(数论)

序列期望

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_nx​1​​,x​2​​,...,x​n​​。给定区间[l1,r1],...,[ln,rn][l_1, r_1],...,[l_n, r_n][l​1​​,r​1​​],...,[l​n​​,r​n​​],变量xix_ix​i​​的值会等概率成为区间[li,ri][l_i, r_i][l​i​​,r​i​​]中的任意一个整数

显然这nnn个随机变量的值会有一共∏i=1n(ri−li+1)\prod_{i=1}^{n} (r_i - l_i + 1) ∏​i=1​n​​(r​i​​−l​i​​+1) 种情况,且每种情况出现的概率为∏i=1n1ri−li+1\prod_{i=1}^{n} \frac{1}{r_i - l_i + 1}∏​i=1​n​​​r​i​​−l​i​​+1​​1​​ 。

对于某种情况,令h=max{x1,x2,...,xn}h= \max{ x_1,x_2,...,x_n}h=max{x​1​​,x​2​​,...,x​n​​},定义这种情况的权值为:∏i=1n(h−xi+1)\prod_{i=1}^{n} (h - x_i + 1)∏​i=1​n​​(h−x​i​​+1).

度度熊想知道权值的期望是多少?请将答案对109+710^9 + 710​9​​+7取模后输出。

PS:不清楚期望是啥?为什么不问问神奇的百度呢?

Input

第一行一个数,表示数据组数TTT。

每组数据第一行一个整数nnn;接下来nnn行,每行两个数,表示lil_il​i​​和rir_ir​i​​。

数据组数T=100,满足:

  • 1≤n≤1001 \le n \le 1001≤n≤100
  • 1≤li≤ri≤1041 \le l_i \le r_i \le 10^41≤l​i​​≤r​i​​≤10​4​​

其中70%的数据满足ri≤100r_i \le 100r​i​​≤100。

Output

每组数据输出一行,每行仅包含一个数,表示期望。

假设答案为pq\frac{p}{q}​q​​p​​,请输出p×q−1 mod 109+7p \times q^{-1} ~mod~10^9+7p×q​−1​​ mod 10​9​​+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。

Statistic | Submit | Clarifications | Back

暴力每个最大值,然后分别求贡献即可。

#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);
    }
}

猜你喜欢

转载自blog.csdn.net/haut_ykc/article/details/81810601