[AGC028B]Removing Blocks(概率与期望)

Posted cnyali-tea

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[AGC028B]Removing Blocks(概率与期望)相关的知识,希望对你有一定的参考价值。

技术图片

Solution:

? 直接计算不是很好搞,于是考虑将代价和变成代价的平均值乘以方案数( \(n!\) )

? 即 \(Ans = \text删除物品的期望代价\times n!\)

? 由期望的线性性质,考虑每一个 \(a_i\) 对期望代价的贡献,对于 \(a_i\)\(a_j\), 若 \(i\)\(j\) 有贡献,必然是第一个删除 \(j\) ,这样 \(a_i\) 的值会被 \(j\) 统计一次,这样的概率为 \(\frac1|j-i|+1\),于是有:
\[ Contribution(a_i) = a_i\sum_j=1^n\frac1|j-i|+1 \]
答案为
\[ \sum_i=1^na_i\sum_j=1^n\frac1|j-i|+1 \]
前缀和优化逆元。

Code

#include <vector>
#include <cmath>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <iostream>
#include <algorithm>

typedef long long LL;
typedef unsigned long long uLL;

#define fir first
#define sec second
#define SZ(x) (int)x.size()
#define MP(x, y) std::make_pair(x, y)
#define PB(x) push_back(x)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define GO debug("GO\n")
#define rep(i, a, b) for (register int i = (a), i##end = (b); (i) <= i##end; ++ (i))
#define drep(i, a, b) for (register int i = (a), i##end = (b); (i) >= i##end; -- (i))
#define REP(i, a, b) for (register int i = (a), i##end = (b); (i) < i##end; ++ (i))

inline int read() 
    register int x = 0; register int f = 1; register char c;
    while (!isdigit(c = getchar())) if (c == '-') f = -1;
    while (x = (x << 1) + (x << 3) + (c xor 48), isdigit(c = getchar()));
    return x * f;

template<class T> inline void write(T x) 
    static char stk[30]; static int top = 0;
    if (x < 0)  x = -x, putchar('-'); 
    while (stk[++top] = x % 10 xor 48, x /= 10, x);
    while (putchar(stk[top--]), top);

template<typename T> inline bool chkmin(T &a, T b)  return a > b ? a = b, 1 : 0; 
template<typename T> inline bool chkmax(T &a, T b)  return a < b ? a = b, 1 : 0; 

#define int LL

using namespace std;

const int maxn = 1e5 + 2;
const int MOD = 1e9 + 7;

LL a[maxn], n;
LL inv[maxn], sum[maxn];

void Input() 
    n = read();
    rep (i, 1, n) a[i] = read();


void Init() 
    inv[0] = 0;
    inv[1] = 1;
    sum[1] = inv[1];
    rep (i, 2, n) 
        inv[i] = (MOD - (MOD / i) * inv[MOD % i] % MOD) % MOD;
        sum[i] = (sum[i - 1] + inv[i]) % MOD;
    


int factor(int n) 
    int ans = 1;
    rep (i, 2, n) ans = ans * i % MOD;
    return ans;


void Solve() 
    LL ans(0);
    rep (i, 1, n) 
        ans = (ans + a[i] * ((sum[i] - sum[0] + sum[n - i + 1] - sum[1] + MOD) % MOD) % MOD ) % MOD;
    
    cout << ans * factor(n) % MOD << endl;


signed main() 

    
    Input();

    Init();

    Solve();

    return 0;

以上是关于[AGC028B]Removing Blocks(概率与期望)的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder AGC033C Removing Coins (博弈论)

AGC033C Removing Coins(博弈论+思维)

Swift 里 SetAdding & Removing Elements

Removing jQuery from GitHub.com frontend

tar: Removing leading `/‘ from member names

Codeforces 496C - Removing Columns