链接:https://www.nowcoder.com/acm/contest/147/E
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
Niuniu likes to play OSU!
We simplify the game OSU to the following problem.
Given n and m, there are n clicks. Each click may success or fail.
For a continuous success sequence with length X, the player can score X^m.
The probability that the i-th click success is p[i]/100.
We want to know the expectation of score.
As the result might be very large (and not integral), you only need to output the result mod 1000000007.
输入描述:
The first line contains two integers, which are n and m. The second line contains n integers. The i-th integer is p[i]. 1 <= n <= 1000 1 <= m <= 1000 0 <= p[i] <= 100
输出描述:
You should output an integer, which is the answer.
示例1
输入
复制
3 4 50 50 50
输出
复制
750000020
说明
000 0 001 1 010 1 011 16 100 1 101 2 110 16 111 81 The exact answer is (0 + 1 + 1 + 16 + 1 + 2 + 16 + 81) / 8 = 59/4. As 750000020 * 4 mod 1000000007 = 59 You should output 750000020.
备注:
If you don't know how to output a fraction mod 1000000007, You may have a look at https://en.wikipedia.org/wiki/Modular_multiplicative_inverse
因为数据很小允许O(n^2)的复杂度,期望有线性可加性也就是E(X+Y)=E(X)+E(Y)。预处理出所有连续段1的期望求和就是所得,每一段连续区间[i+1,j-1]的期望等于i+1~j-1成功的概率相乘然后再乘以i和j失败的概率,最后乘上(i-j-1)^m
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll n,m,mu[1005],a[1005],pre[1005][1005];
ll qpow(ll a,ll b)
{
a=a%mod;
ll base=a;
ll ans=1;
while(b)
{
if(b&1) ans=ans*base%mod;
base=base*base%mod;
b>>=1;
}
return ans;
}
int main()
{
while(scanf("%lld %lld",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
mu[i]=qpow(i,m)%mod;
}
ll inv=qpow(100,mod-2);
a[0]=0,a[n+1]=0;
for(int i=1;i<=n;i++)
{
pre[i][i]=a[i]*inv%mod;
for(int j=i+1;j<=n;j++)
{
pre[i][j]=pre[i][j-1]*a[j]%mod*inv%mod;
}
}
ll ans=0;
for(int i=0;i<=n;i++)
{
for(int j=i+2;j<=n+1;j++)
{
ans+=pre[i+1][j-1]*mu[j-i-1]%mod*(100-a[i])%mod*inv%mod*(100-a[j])%mod*inv%mod;
ans%=mod;
}
}
printf("%lld\n",ans);
}
return 0;
}