メモジャンボ

良い感じのブログタイトル募集中

期待値の線形性, 逆元 (AGC 028 B問題)

SoundHound Inc. Programming Contest 2018のC問題と雰囲気似てますね
こういう数学っぽい問題マジで無理すぎて毎回解説見て(o・ω・o)ホェーwwwってなってます

問題

以下ネタバレ注意

逆元の実装はけんちょんさんの記事「よくやる二項係数 (nCk mod. p)、逆元 (a^-1 mod. p) の求め方」を参考にしました。

  1. const int MOD = 1000000007;
  2. const int MAX = 100010;
  3.  
  4.  
  5. ll inv[MAX];//逆元
  6. void makeInv() {
  7. inv[1] = 1;
  8. FOR(i, 2, MAX) {
  9. inv[i]= MOD - inv[MOD%i] * (MOD / i) % MOD;
  10. }
  11. }
  12.  
  13. //階乗のmod
  14. ll FactMod(int n, int m) {
  15. ll x = 1;
  16. FOR(i, 1, n + 1) {
  17. x *= i;
  18. x %= m;
  19. }
  20. return x;
  21. }
  22.  
  23. ll cum[MAX];//累積和
  24. ll Ex[MAX];//ブロックiのコストがかかる回数の期待値
  25. ll A[MAX];
  26.  
  27. int main() {
  28.  
  29. int N; cin >> N;
  30. FOR(i,1, N+1) {
  31. cin >> A[i];
  32. }
  33.  
  34. makeInv();
  35. ll fact = FactMod(N, MOD);
  36.  
  37. cum[0] = 0;
  38. cum[1] = 1;
  39. FOR(i, 2, MAX) {
  40. cum[i] = (cum[i - 1] + inv[i]) % MOD;
  41. }
  42.  
  43. FOR(i,1, N + 1) {
  44. Ex[i] = cum[i] - cum[0] + cum[N - i + 1] - cum[1];
  45. Ex[i] %= MOD;
  46. }
  47.  
  48. ll ans = 0;
  49. FOR(i, 1, N + 1) {
  50. ans += Ex[i] * A[i];
  51. ans %= MOD;
  52. }
  53. ans *= fact;
  54. ans %= MOD;
  55.  
  56. cout << ans << endl;
  57. }