【題解】 [Cnoi2020]線形生物 期望dp
阿新 • • 發佈:2020-09-19
Legend
給定 \(1\to 2 \to \cdots \to n \to n+1\) 的邊和 \(m\) 條往回走的有向邊,長度都是 \(1\)。站在一個點時等概率選擇一條出邊,求 \(1\to n+1\) 期望長度。
\(1 \le n ,m \le 10^6\)。
Editorial
考慮一個套路:設 \(f_{i}\) 表示從 \(i\to i+1\) 行走距離的期望,答案就是 \(\sum\limits_{i=1}^n f_i\)。
這個東西也很好求……
Code
#include <bits/stdc++.h> #define LL long long int read(){ char k = getchar(); int x = 0; while(k < '0' || k > '9') k = getchar(); while(k >= '0' && k <= '9') x = x * 10 + k - '0' ,k = getchar(); return x; } const LL MOD = 998244353; LL qpow(LL a ,LL b ,LL p = MOD){ LL Ans = 1; while(b){if(b & 1) Ans = Ans * a % p; a = a * a % p ,b >>= 1; }return Ans; } const int MX = 1e6 + 233; LL dp[MX] ,zh[MX] ,qzh[MX]; int n ,m; std::vector<int> fz[MX]; int main(){ read(); n = read() ,m = read(); for(int i = 1 ,u ,v ; i <= m ; ++i){ u = read() ,v = read(); if(u != v) fz[u].push_back(v); else zh[u]++; } LL Ans = 0; for(int i = 1 ; i <= n ; ++i){ int ch = fz[i].size() + 1 + zh[i]; LL inv = qpow(ch ,MOD - 2); dp[i] = 1; for(auto j : fz[i]){ dp[i] = (dp[i] + inv * (qzh[i - 1] - qzh[j - 1] + MOD)) % MOD; } dp[i] = dp[i] * ch % MOD; // printf("f[%d] = %lld\n" ,i ,dp[i]); Ans = (Ans + dp[i]) % MOD; qzh[i] = (qzh[i - 1] + dp[i]) % MOD; } using namespace std; cout << Ans << endl; return 0; }