传送门
首先对于第一问,其实等价于对
k
k
k个物品各自分配一个数字:
c
1
,
c
2
,
c
3
,
.
.
.
,
c
k
c_1,c_2,c_3,...,c_k
c1,c2,c3,...,ck,满足
A
≤
c
1
≤
c
2
≤
c
3
≤
.
.
.
≤
B
A\le c_1\le c_2\le c_3\le...\le B
A≤c1≤c2≤c3≤...≤B,然后问方案数。
不妨设 c 0 = A , c k + 1 = B c_0=A,c_{k+1}=B c0=A,ck+1=B,那么可以求出关于 c c c的差分数组为 d i = c i − c i − 1 d_i=c_i-c_{i-1} di=ci−ci−1,也就是 d 1 , d 2 , . . . , d k + 1 d_1,d_2,...,d_{k+1} d1,d2,...,dk+1,由于 c c c数组单调不减,故满足 d ≥ 0 d\ge 0 d≥0,并且有 d 1 + d 2 + . . . + d k + 1 = B − A d_1+d_2+...+d_{k+1}=B-A d1+d2+...+dk+1=B−A,这个问题相当于在问你为 d d d分配一个非负值满足此表达式,这就是一个非常典型的组合学问题了,利用隔板法容易发现答案为 C B − A + k k C_{B-A+k}^k CB−A+kk。
然后再看第二问,求整个序列的和的期望,还是像上一问一样考虑子问题,也就是对于 k k k个物品分配的数字 c 1 , c 2 , . . . , c k c_1,c_2,...,c_k c1,c2,...,ck在满足 A ≤ c 1 ≤ . . . ≤ c k ≤ B A\le c_1\le ...\le c_{k}\le B A≤c1≤...≤ck≤B的情况下的平均值,如果 k = 1 k=1 k=1的话容易发现答案为 A + B 2 \frac {A+B}2 2A+B,然后再根据对称性可以发现当 k k k变大后这个平均值不可能不是 A + B 2 \frac{A+B}2 2A+B,如果平均值偏小的话就会不符合数学中的对称性,因此 E ( c ) = A + B 2 E(c)=\frac{A+B}2 E(c)=2A+B,那么后面的就好做了。
#include <bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long ll;
const int maxn = 2e6+5;
const int mod = 1e9+9;
int a[maxn],b[maxn],fac[maxn],fav[maxn];
int C(int a,int b){
if(a<b)return 0;
return 1ll*fac[a]*fav[a-b]%mod*fav[b]%mod;
}
int qpow(int a,int b,int c){
int ans=1;
while(b){
if(b&1)ans=1ll*ans*a%c;
b>>=1;
a=1ll*a*a%c;
}
return ans;
}
int main(){
int t;
fac[0]=1;
for(int i=1;i<maxn;++i)fac[i]=1ll*fac[i-1]*i%mod;
fav[maxn-1]=qpow(fac[maxn-1],mod-2,mod);
for(int i=maxn-2;i>=0;--i)fav[i]=1ll*fav[i+1]*(i+1)%mod;
scanf("%d",&t);
int kase=0;
while(t--){
int n,m;
scanf("%d%d",&n,&m);
int ans1=1;
ll ans2=0;
for(int i=1;i<=m;++i)scanf("%d",&a[i]);
for(int i=1;i<=m;++i){
scanf("%d",&b[i]);
}
for(int i=1;i<m;++i){
int k=a[i+1]-a[i]-1;
ans1=1ll*ans1*C(b[i+1]-b[i]+k,k)%mod;
ans2+=1ll*(b[i]+b[i+1])*k;
ans2+=2ll*b[i];
}
ans2+=2ll*b[m];
printf("Case #%d: %d %.3lf\n",++kase,ans1,ans2/2.0);
}
}