Description
给出一长度为 n n 的序列 a1,...,an a 1 , . . . , a n ,每次操作等概率的从 1 1 ~ n n 中选一个数 x x ,把这 n n 个数去掉 ax a x 后的乘积加到答案里,然后把 ax a x 减一,问 k k 次操作后答案的期望值
Input
第一行输入两个整数 n,k n , k ,之后输入 n n 个整数 ai(1≤n≤5000,1≤k≤109,0≤ai≤109) a i ( 1 ≤ n ≤ 5000 , 1 ≤ k ≤ 10 9 , 0 ≤ a i ≤ 10 9 )
Output
保证答案可以写成最简分数形式 PQ P Q ,输出 P⋅Q−1 mod109+7 P ⋅ Q − 1 m o d 10 9 + 7
Sample Input
2 1
5 5
Sample Output
5
Solution
假设某次操作前这 n n 个数字变成 ai−bi a i − b i , bi b i 为 i i 被选中的次数
当前操作选中了 x x ,那么该次操作的贡献为 ∏i≠x(ai−bi)=∏i=1n(ai−bi)−(ai−(bi+1))∏i≠x(ai−bi) ∏ i ≠ x ( a i − b i ) = ∏ i = 1 n ( a i − b i ) − ( a i − ( b i + 1 ) ) ∏ i ≠ x ( a i − b i )
不妨设 ci=bi,i≠x,cx=bx+1 c i = b i , i ≠ x , c x = b x + 1 为该次操作结束后 i i 被选中的次数
那么本次操作的贡献可以写成: ∏i=1n(ai−bi)−∏i=1n(ai−ci) ∏ i = 1 n ( a i − b i ) − ∏ i = 1 n ( a i − c i )
计算该交错和得总贡献为 ∏i=1nai−∏i=1n(ai−bi) ∏ i = 1 n a i − ∏ i = 1 n ( a i − b i ) ,其中 bi b i 为 k k 次操作后 i i 被选中的次数, ∑i=1nbi=k ∑ i = 1 n b i = k
故答案的期望值为 1nk∑∑i=1nbi=kk!∏i=1nbi!(∏i=1nai−∏i=1n(ai−bi))=∏i=1nai−k!nk∑∑i=1nbi=k∏i=1nai−bibi! 1 n k ∑ ∑ i = 1 n b i = k k ! ∏ i = 1 n b i ! ( ∏ i = 1 n a i − ∏ i = 1 n ( a i − b i ) ) = ∏ i = 1 n a i − k ! n k ∑ ∑ i = 1 n b i = k ∏ i = 1 n a i − b i b i !
令 Pj(x) P j ( x ) 为上述求和式中第 j j 项对答案的贡献,则有 Pj(x)=∑i≥0aj−ii!xi,1≤j≤n P j ( x ) = ∑ i ≥ 0 a j − i i ! x i , 1 ≤ j ≤ n
化简得 Pj(x)=aj∑i≥01i!xi−x∑i≥11(i−1)!xi−1=(aj−x)⋅ex P j ( x ) = a j ∑ i ≥ 0 1 i ! x i − x ∑ i ≥ 1 1 ( i − 1 ) ! x i − 1 = ( a j − x ) ⋅ e x
记 f(k)=∑∑i=1nbi=k∏i=1nai−bibi! f ( k ) = ∑ ∑ i = 1 n b i = k ∏ i = 1 n a i − b i b i ! ,考虑其生成函数 F(x)=∑i≥0f(i)⋅xi F ( x ) = ∑ i ≥ 0 f ( i ) ⋅ x i
有 F(x)=∏j=1nPj(x)=enx⋅∏j=1n(aj−x)=enx⋅G(x) F ( x ) = ∏ j = 1 n P j ( x ) = e n x ⋅ ∏ j = 1 n ( a j − x ) = e n x ⋅ G ( x )
O(n2) O ( n 2 ) 直接计算得 G(x)=∑i=0ngi⋅xi G ( x ) = ∑ i = 0 n g i ⋅ x i ,进而有:
f(k)=[xk]F(x)=∑i=0min(n,k)[xi]G(x)⋅[xk−i]enx=∑i=0min(n,k)gi⋅nk−i(k−i)! f ( k ) = [ x k ] F ( x ) = ∑ i = 0 m i n ( n , k ) [ x i ] G ( x ) ⋅ [ x k − i ] e n x = ∑ i = 0 m i n ( n , k ) g i ⋅ n k − i ( k − i ) !
故答案为 ∏i=1nai−k!nkf(k)=∏i=1nai−∑i=0min(n,k)gi⋅∏j=k−i+1kjni ∏ i = 1 n a i − k ! n k f ( k ) = ∏ i = 1 n a i − ∑ i = 0 m i n ( n , k ) g i ⋅ ∏ j = k − i + 1 k j n i
Code
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=5005;
#define mod 1000000007
int n,k,v[maxn],a[maxn],b[maxn];
void inc(int &x,int y)
{
x=x+y>=mod?x+y-mod:x+y;
}
void dec(int &x,int y)
{
x=x-y<0?x-y+mod:x-y;
}
int Pow(int a,int b)
{
int ans=1;
while(b)
{
if(b&1)ans=(ll)ans*a%mod;
a=(ll)a*a%mod;
b>>=1;
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
int ans=1;
for(int i=1;i<=n;i++)scanf("%d",&v[i]),ans=(ll)ans*v[i]%mod;
a[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j1],a[j]);
}
for(int j=0;j<=i;j++)a[j]=b[j],b[j]=0;
}
int m=min(n,k),p=1,q=1,inv=Pow(n,mod-2);
for(int i=0;i<=m;i++)
{
dec(ans,(ll)p*a[i]%mod*q%mod);
p=(ll)p*(k-i)%mod;
q=(ll)q*inv%mod;
}
printf("%d\n",ans);
}
return 0;
}