牛客网暑期ACM多校训练营(第九场) E-Music Game(思路+大数逆元)

链接:https://www.nowcoder.com/acm/contest/147/E
来源:牛客网
 

题目描述

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

 

思路:首先肯定不可能枚举,但是想到只连续111..的计算数学期望,所以对于一个数是可以把他拆开的,比如11011101,可以拆开成(2^m+3^m+1^m)*P,这样就可以想到所有的数如果都这样拆开,这样就转换成了一个求不同大小不同位置的连续区间值了,我们遍历每一个不同大小连续区间,同时保证两边都是零,这样就可以把所有的数的连续的1...计算上了。

举个例子 :(q表示0的概率,p表示1的概率)

0 0  | 0 1       q1*q2*q3*p4

1 0  | 0 1       p1*q2*q3*p4

1 1  | 0 1       p1*p2*q3*p4

0 1  |  0 1      q1*p2*q3*p4       

此时遍历到最后一位是个1,这样前一位保证是0 ,对于有这种组合的所有数已经如上图排列,我们会发现其他地方即前两位是全排列,所以算这种情况的全排列的时候,(q1*q2+p1*q2+p1*p2+q1*p2)*q3*p4 ,括号内的值为1,所以这种情况的期望值就是

1^m*q3*p4,这样跑一个1e6的遍历所有情况加和就是答案了。

代码:

#include
using namespace std;
typedef long long LL;

#define M(a,b) memset(a,b,sizeof(a))
#define pb push_back

const int maxn = 100000+5;
const LL mod = 1000000007;
LL qp(LL a,LL p) {
    LL res=1;
    while(p) {
        if (p&1) {
            res=res*a;
            if (res>=mod) {
                res%=mod;
            }
        }
        a=a*a;
        if (a>=mod) {
            a%=mod;
        }
        p>>=1;
    }
    return res;
}

LL dp[1005][1005];
LL f[1005];
LL p1[1005];
LL p2[1005];
LL inv;
LL get(LL a) {
    return a*inv%mod;
}
int main() {
    int n,m;
    scanf("%d%d",&n,&m);
    inv=qp(100,mod-2);
    p1[0]=1;
    p2[0]=1;
    p2[n+1]=p1[n+1]=1;
    for (int i=1;i<=n;++i) {
        scanf("%lld",p1+i);
        p2[i]=get(100-p1[i]);
        p1[i]=get(p1[i]);
        dp[i][0]=1;
    }
    f[1]=1;
    for (int i=2;i<=n;++i) {
        f[i]=qp(i,m);
    }
    LL ans=0;
    for (int i=1;i<=n;++i) {
        for (int j=1;j<=n;++j) {
            if (i+j-1>n) {
                break;
            }
            dp[i][j]=dp[i][j-1]*p1[i+j-1]%mod;
            LL tmp ;
            tmp=p2[i-1]*p2[i+j]%mod*dp[i][j]%mod;
            ans=(ans+tmp*f[j])%mod;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

 

你可能感兴趣的:(思路题,n)