题目
题目大意
若 x x x是一个数列,定义函数 B ( x ) B(x) B(x)表示:将数列中连续的相同的作为一段的段数。例如 B ( [ 3 , 3 , 6 , 1 , 6 , 6 , 6 ] ) = 4 B([3,3,6,1,6,6,6])=4 B([3,3,6,1,6,6,6])=4,现在有一个 n n n个数的数组 a a a, a i ∈ [ l i , r i ] a_i\in[l_i,r_i] ai∈[li,ri], a a a不确定,求 B ( a ) 2 B(a)^2 B(a)2的期望,期望是一个既约分数 p q \dfrac{p}{q} qp,输出 p ⋅ q − 1 m o d    1 0 9 + 1 p\cdot q^{-1}\mod 10^9+1 p⋅q−1mod109+1。
分析
对于一个确定的数列
x
x
x(
x
x
x的长度为
n
n
n):
B
(
x
)
B(x)
B(x)和下面定义的
T
(
i
)
T(i)
T(i)都是一个函数。
定义:若
x
i
≠
x
i
+
1
x_i\neq x_{i+1}
xi̸=xi+1,
T
(
i
)
=
1
T(i)=1
T(i)=1,否则
T
(
i
)
=
0
T(i)=0
T(i)=0,并规定
T
(
n
)
=
1
T(n)=1
T(n)=1。显然
B
(
x
)
=
∑
i
=
1
n
T
(
i
)
B(x)=\sum\limits_{i=1}^{n}T(i)
B(x)=i=1∑nT(i)。
于是
B
(
x
)
2
=
(
∑
i
=
1
n
T
(
i
)
)
2
=
∑
i
=
1
n
∑
j
=
1
n
[
T
(
i
)
T
(
j
)
]
B(x)^2=\left(\sum\limits_{i=1}^{n}T(i)\right)^2=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\left[T(i)T(j)\right]
B(x)2=(i=1∑nT(i))2=i=1∑nj=1∑n[T(i)T(j)]。
\\
对于不确定的数列
a
a
a:
B
(
a
)
2
B(a)^2
B(a)2和对应的
T
(
i
)
T(i)
T(i)自然成了随机变量。
所以我们要求的是这个随机变量的期望,即
E
(
∑
i
=
1
n
∑
j
=
1
n
[
T
(
i
)
T
(
j
)
]
)
E\left(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\left[T(i)T(j)\right]\right)
E(i=1∑nj=1∑n[T(i)T(j)])
由于期望可以加和,我们要求的变为了
∑
i
=
1
n
∑
j
=
1
n
E
(
T
(
i
)
T
(
j
)
)
\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}E(T(i)T(j))
i=1∑nj=1∑nE(T(i)T(j))
分两类讨论:
- T ( i ) T ( j ) = 1 T(i)T(j)=1 T(i)T(j)=1时,意味着 a i a_i ai跟 a i + 1 a_{i+1} ai+1不一样,并且 a j a_j aj跟 a j + 1 a_{j+1} aj+1不一样
- T ( i ) T ( j ) = 0 T(i)T(j)=0 T(i)T(j)=0时,即 T ( i ) = 0 T(i)=0 T(i)=0或 T ( j ) = 0 T(j)=0 T(j)=0或都等于 0 0 0,表示的意义见定义
第二种情况对期望的贡献为
0
0
0,不用考虑,只考虑第一种情况对期望的贡献:
1
×
P
(
T
(
i
)
T
(
j
)
=
1
)
=
P
(
T
(
i
)
T
(
j
)
=
1
)
1\times P(T(i)T(j)=1)=P(T(i)T(j)=1)
1×P(T(i)T(j)=1)=P(T(i)T(j)=1)(
P
(
T
(
i
)
T
(
j
)
=
1
)
P(T(i)T(j)=1)
P(T(i)T(j)=1)为
T
(
i
)
T
(
j
)
=
1
T(i)T(j)=1
T(i)T(j)=1发生的概率)
于是问题又变为了求
∑
i
=
1
n
∑
j
=
1
n
P
(
T
(
i
)
T
(
j
)
=
1
)
\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}P(T(i)T(j)=1)
i=1∑nj=1∑nP(T(i)T(j)=1)
换句话说,如果事件
f
(
i
)
f(i)
f(i)表示
T
(
i
)
=
1
T(i)=1
T(i)=1,我们要求
∑
i
=
1
n
∑
j
=
1
n
P
(
f
(
i
)
f
(
j
)
)
\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}P(f(i)f(j))
i=1∑nj=1∑nP(f(i)f(j))(
P
(
f
(
i
)
f
(
j
)
)
P(f(i)f(j))
P(f(i)f(j))表示的是
T
(
i
)
=
1
T(i)=1
T(i)=1和
T
(
j
)
=
1
T(j)=1
T(j)=1这两件事同时发生的概率)
-
显然 ∣ i − j ∣ ≥ 2 |i-j|\geq 2 ∣i−j∣≥2时, f ( i ) f(i) f(i)与 f ( j ) f(j) f(j)相互独立,则 P ( f ( i ) f ( j ) ) = P ( f ( i ) ) ⋅ P ( f ( j ) ) P(f(i)f(j))=P(f(i))\cdot P(f(j)) P(f(i)f(j))=P(f(i))⋅P(f(j)),又因为 P ( f ( i ) ) = P ( a i 和 a i + 1 不 同 ) = 1 − P ( a i 和 a i + 1 相 同 同 ) = ∣ [ l i , r i ] ∩ [ l i + 1 , r i + 1 ] ∣ ( r i − l i + 1 ) ( r i + 1 − l i + 1 + 1 ) ( 1 ≤ i ≤ n ) P(f(i))=P(a_i和a_{i+1}不同)=1-P(a_i和a_{i+1}相同同)=\dfrac{|[l_i,r_i]\cap[l_{i+1},r_{i+1}]|}{(r_i-l_i+1)(r_{i+1}-l_{i+1}+1)}(1\leq i\leq n) P(f(i))=P(ai和ai+1不同)=1−P(ai和ai+1相同同)=(ri−li+1)(ri+1−li+1+1)∣[li,ri]∩[li+1,ri+1]∣(1≤i≤n)所以此时 P ( f ( i ) f ( j ) ) P(f(i)f(j)) P(f(i)f(j))可以求。
-
如果 ∣ i − j ∣ = 1 |i-j|=1 ∣i−j∣=1即 i i i, j j j相邻, f ( i ) f(i) f(i)和 f ( i ) f(i) f(i)就相互有影响(想不清楚为什么有影响就再看 f ( i ) f(i) f(i)和 T ( i ) T(i) T(i)的定义)了,但是 P ( f ( i ) f ( j ) ) P(f(i)f(j)) P(f(i)f(j))容斥一下也不难算:不妨设 j = i + 1 j=i+1 j=i+1,则 P ( f ( i ) f ( j ) ) = P ( f ( i ) f ( i + 1 ) ) = 1 − P ( a i 和 a i + 1 相 同 ) − P ( a i + 1 和 a i + 2 相 同 ) + P ( a i 和 a i + 1 和 a i + 2 相 同 ) P(f(i)f(j))=P(f(i)f(i+1))=1-P(a_i和a_{i+1}相同)-P(a_{i+1}和a_{i+2}相同)+P(a_i和a_{i+1}和a_{i+2}相同) P(f(i)f(j))=P(f(i)f(i+1))=1−P(ai和ai+1相同)−P(ai+1和ai+2相同)+P(ai和ai+1和ai+2相同)所以此时 P ( f ( i ) f ( j ) ) P(f(i)f(j)) P(f(i)f(j))也可以求。
-
如果 i = j i=j i=j,显然 P ( f ( i ) f ( j ) ) = P ( f ( i ) ) P(f(i)f(j))=P(f(i)) P(f(i)f(j))=P(f(i))。
这样看来是 O ( n 2 ) O(n^2) O(n2)的,但是,对于每个 i i i,所有的满足 i − j ≥ 2 i-j\geq 2 i−j≥2的 P ( f ( j ) ) P(f(j)) P(f(j))可以用前缀和处理,然后根据分配率一起乘 P ( f ( i ) ) P(f(i)) P(f(i)), j − i ≥ 2 j-i\geq 2 j−i≥2也可以算,这样一来就变成 O ( 1 ) O(1) O(1)啦。
代码
关于分数的处理,我写了分数结构体,分数的加减乘时分子和分母随时都可以取模,原因如下:
- 分子显然可以取模。
- 对于分母,最后是以逆元的形式输出,由于逆元是根据费马小定理求的,所以 m − 1 % p = m p − 1 % p m^{-1}\%p=m^{p-1}\%p m−1%p=mp−1%p,又因为 m p − 1 % p = ( m % p ) p − 1 % p m^{p-1}\%p=(m\%p)^{p-1}\%p mp−1%p=(m%p)p−1%p,所以 m − 1 % p = ( m % p ) − 1 % p m^{-1}\%p=(m\%p)^{-1}\%p m−1%p=(m%p)−1%p,故分母取模对逆元无影响。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 200000
#define LL long long
#define MOD 1000000007
int N;
LL L[MAXN+5],R[MAXN+5];
LL Pow(LL x,LL y){
LL ret=1ll;
while(y){
if(y&1)
ret=(ret*x)%MOD;
y>>=1;
x=(x*x)%MOD;
}
return ret;
}
LL Inv(LL x){
return Pow(x,MOD-2);
}
struct Fraction{
LL A,B;
Fraction(){A=0;B=1;}
Fraction(int a,int b):
A(a),B(b){}
Fraction operator + (Fraction m){
return Fraction((A*m.B%MOD+B*m.A%MOD)%MOD,B*m.B%MOD);
}
Fraction operator - (Fraction m){
return Fraction(((A*m.B%MOD-B*m.A%MOD)%MOD+MOD)%MOD,B*m.B%MOD);
}
Fraction operator * (Fraction m){
return Fraction(A*m.A%MOD,B*m.B%MOD);
}
}F[MAXN+5],G[MAXN+5],Sum[MAXN+5];
//F[i]是f(i)的概率
//G[i]是f(i)和f(i+1)同时发生的概率
//Sum[i]=F[1]+...+F[i]
LL I(int L1,int R1,int L2,int R2){//求交集的大小
return max(0,min(R1,R2)-max(L1,L2)+1);
}
int main(){
scanf("%d",&N);
for(int i=1;i<=N;i++)
scanf("%lld",&L[i]);
for(int i=1;i<=N;i++)
scanf("%lld",&R[i]);
for(int i=1;i<=N;i++){
F[i]=Fraction(1,1)-
Fraction(I(L[i],R[i],L[i+1],R[i+1])%MOD,
(R[i]-L[i]+1)*(R[i+1]-L[i+1]+1)%MOD);
Sum[i]=Sum[i-1]+F[i];
}
for(int i=1;i<=N-1;i++){
LL All=(R[i]-L[i]+1)*(R[i+1]-L[i+1]+1)%MOD*(R[i+2]-L[i+2]+1)%MOD;
G[i]=Fraction(1,1)-
Fraction(I(L[i],R[i],L[i+1],R[i+1])*(R[i+2]-L[i+2]+1)%MOD,All)-
Fraction(I(L[i+1],R[i+1],L[i+2],R[i+2])*(R[i]-L[i]+1)%MOD,All)+
Fraction(I(max(L[i],L[i+1]),min(R[i],R[i+1]),L[i+2],R[i+2]),All);
}
Fraction Ans(0,1);
for(int i=1;i<=N;i++){
if(i>1){
Ans=Ans+F[i]*Sum[i-2];
Ans=Ans+G[i-1];
}
if(i<N){
Ans=Ans+F[i]*(Sum[N]-Sum[i+1]);
Ans=Ans+G[i];
}
Ans=Ans+F[i];
}
//不需要约分
printf("%lld",Ans.A*Inv(Ans.B)%MOD);
}