列表

详情


NC208061. 羽毛

描述

Madeline逃离了镜之寺庙之后,决定与Badeline交谈。Madeline决定不再需要Badeline,并让Madeline自由。Badeline害怕被抛弃,抓住了Madeline并使其焦虑症发作。Madeline试图臆想出一根羽毛让自己平静下来,但是她失败了。Madeline与Badeline一同跌落到一个深水洞穴中。那根羽毛则在空中自由飘动。

为了简化模型,将这个地图分为个点,以及条带权单向边。这个羽毛在第秒时在点,则这根羽毛在第秒时会随机选择点的一条出边到达点,如果点没有出边则这根羽毛就就留在点。

可能会有重边或者自环。

在第秒的时候羽毛会等概率地出现在这个点的任意一个点,现在Madeline想知道羽毛在前秒间走过的边权之和的期望是多少。

结果对(质数)取模。保证答案是有理数。如果你的答案是,那么你需要输出的答案ans满足

输入描述

第一行为三个整数

接下来行,每行三个整数,表示存在一条从且边权为的有向边。

输出描述

输出答案对取模的结果。

示例1

输入:

2 2 1
1 1 1
1 2 1

输出:

9630409

说明:

{0}秒时羽毛出现在点{1}时,走过的边权之和只能为{1}
{0}秒时羽毛出现在点{2}时,走过的边权之和只能为{0}
答案即\frac{(1+0)}{2}=\frac{1}{2}

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 321ms, 内存消耗: 1308K, 提交时间: 2020-07-18 18:55:18

#include<bits/stdc++.h>
using namespace std;
const int MOD = 19260817, N = 111;
int p;
void add(int &x, int y) {
  x += y;
  if(x >= MOD) x -= MOD;
}
void sub(int &x, int y) {
  x -= y;
  if(x < 0) x += MOD;
}
struct mat {
  int a[N][N];
  mat() {
    memset(a, 0, sizeof a);
  }
  int* operator[](const int &x) {
    return a[x];
  }
  const int* operator[](const int &x) const {
    return a[x];
  }
  friend mat operator*(const mat &x, const mat &y) {
    mat z;
    for(int i = 0; i < p; i++) {
      for(int j = 0; j < p; j++) {
        for(int k = 0; k < p; k++) {
          add(z[i][j], 1ll * x[i][k] * y[k][j] % MOD);
        }
      }
    }
    return z;
  }
};
int siz[N], inv[50005];
vector<pair<int, int>> edg[N];
int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  inv[1] = 1;
  for(int i = 2; i < 50005; i++) {
    inv[i] = 1ll * (MOD - MOD / i) * inv[MOD % i] % MOD;
  }
  int n, m, k; cin >> n >> m >> k;
  p = n + 1;
  for(int i = 0; i < m; i++) {
    int u, v, w; cin >> u >> v >> w;
    // assert(w >= 0 && w < 19260817);
    u--, v--;
    edg[u].emplace_back(v, w);
    siz[u]++;
  }
  for(int i = 0; i < n; i++) {
    if(siz[i] == 0) {
      edg[i].emplace_back(i, 0);
      siz[i]++;
    }
  }
  mat ans, a;
  for(int i = 0; i < p; i++) {
    ans[i][i] = 1;
  }
  a[n][n] = 1;
  for(int i = 0; i < n; i++) {
    for(const pair<int, int> &pir: edg[i]) {
      const int u = i, v = pir.first, w = pir.second;
      add(a[u][v], inv[siz[u]]);
      add(a[u][n], 1ll * w * inv[siz[u]] % MOD);
    }
  }
  while(k) {
    if(k & 1) {
      ans = ans * a;
    }
    a = a * a;
    k >>= 1;
  }
  int res = 0;
  for(int i = 0; i < n; i++) {
    add(res, ans[i][n]);
  }
  res = 1ll * res * inv[n] % MOD;
  cout << res << '\n';
}

上一题